diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..d2ea021a8 --- /dev/null +++ b/404.html @@ -0,0 +1,2825 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ +

404 - Not found

+ +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..cdcfdff63 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +wpbrowser.wptestkit.dev diff --git a/DispatcherAPI/index.html b/DispatcherAPI/index.html new file mode 100644 index 000000000..47084f13f --- /dev/null +++ b/DispatcherAPI/index.html @@ -0,0 +1,3646 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dispatcher API - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + + + +

Dispatcher API

+ +

An API to dispatch and subscribe to events fired during tests execution.

+

Events dispatched by Codeception

+

You can subscribe to the following events dispatched by Codeception in either the global bootstrap file +(usually tests/_bootstrap.php), or in a suite bootstrap file (usually tests/<suite>/_bootstrap.php) using the +Event Dispatcher Bridge extension:

+
    +
  • Codeception\Events::SUITE_BEFORE
  • +
  • Codeception\Events::SUITE_AFTER
  • +
  • CodeceptionventsEvents::TEST_START
  • +
  • CodeceptionventsEvents::TEST_BEFORE
  • +
  • CodeceptionventsEvents::STEP_BEFORE
  • +
  • CodeceptionventsEvents::STEP_AFTER
  • +
  • CodeceptionventsEvents::TEST_FAIL
  • +
  • CodeceptionventsEvents::TEST_ERROR
  • +
  • CodeceptionventsEvents::TEST_PARSED
  • +
  • CodeceptionventsEvents::TEST_INCOMPLETE
  • +
  • CodeceptionventsEvents::TEST_SKIPPED
  • +
  • CodeceptionventsEvents::TEST_WARNING
  • +
  • CodeceptionventsEvents::TEST_USELESS
  • +
  • CodeceptionventsEvents::TEST_SUCCESS
  • +
  • CodeceptionventsEvents::TEST_AFTER
  • +
  • CodeceptionventsEvents::TEST_END
  • +
  • CodeceptionventsEvents::TEST_FAIL_PRINT
  • +
  • CodeceptionventsEvents::RESULT_PRINT_AFTER
  • +
+

In the global bootstrap file (usually tests/_bootstrap.php), or the suite bootstrap file (usually +tests/<suite>/_bootstrap.php), subscribe to the Codeception events by providing a callback function that will accept +different parameters depending on the event being dispatched:

+
<?php
+
+use Codeception\Events;
+use Codeception\Event\SuiteEvent
+use Codeception\Event\TestEvent;
+use Codeception\Event\StepEvent;
+use Codeception\Event\PrintResultEvent;
+use lucatume\WPBrowser\Events\Dispatcher;
+
+Dispatcher::addListener(Events::SUITE_BEFORE, function (SuiteEvent $suiteEvent) {
+    codecept_debug('Running on SUITE BEFORE');
+});
+
+Dispatcher::addListener(Events::SUITE_AFTER, function (SuiteEvent $suiteEvent) {
+    codecept_debug('Running on SUITE AFTER');
+});
+
+Dispatcher::addListener(Events::TEST_START, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST START');
+});
+
+Dispatcher::addListener(Events::TEST_BEFORE, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST BEFORE');
+});
+
+Dispatcher::addListener(Events::STEP_BEFORE, function (StepEvent $stepEvent) {
+    codecept_debug('Running on STEP BEFORE');
+});
+
+Dispatcher::addListener(Events::STEP_AFTER, function (StepEvent $stepEvent) {
+    codecept_debug('Running on STEP AFTER');
+});
+
+Dispatcher::addListener(Events::TEST_FAIL, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST FAIL');
+});
+
+Dispatcher::addListener(Events::TEST_ERROR, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST ERROR');
+});
+
+Dispatcher::addListener(Events::TEST_PARSED, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST PARSED');
+});
+
+Dispatcher::addListener(Events::TEST_INCOMPLETE, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST INCOMPLETE');
+});
+
+Dispatcher::addListener(Events::TEST_SKIPPED, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST SKIPPED');
+});
+
+Dispatcher::addListener(Events::TEST_WARNING, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST WARNING');
+});
+
+Dispatcher::addListener(Events::TEST_USELESS, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST USELESS');
+});
+
+Dispatcher::addListener(Events::TEST_SUCCESS, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST SUCCESS');
+});
+
+Dispatcher::addListener(Events::TEST_AFTER, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST AFTER');
+});
+
+Dispatcher::addListener(Events::TEST_END, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST END');
+});
+
+Dispatcher::addListener(Events::TEST_FAIL_PRINT, function (PrintResultEvent $printResultEvent) {
+    codecept_debug('Running on TEST FAIL PRINT');
+});
+
+Dispatcher::addListener(Events::RESULT_PRINT_AFTER, function (PrintResultEvent $printResultEvent) {
+    codecept_debug('Running on RESULT PRINT AFTER');
+});
+
+

Events dispatched by wp-browser

+

The project dispatches its own events, allowing you to subscribe to them to control the test state and execution.
+To subscribe to the events dispatched by wp-browser, you do not need to use the +Event Dispatcher Bridge extension.

+

Events dispatched by the WPLoader module

+

The WPLoader module will dispatch events during its initialization.

+
EVENT_BEFORE_LOADONLY
+

This event fires before WordPress is loaded by the WPLoader module when loadOnly is set to true.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+

WordPress is not loaded yet, so you cannot use functions or classes defined by WordPress, themes or plugins here.
+You can interact with the WordPress installation and use the lucatume\WPBrowser\WordPress\PreloadFilters class to +hook on actions and filters that will be fired by WordPress once loaded.

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPLoader;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPLoader::EVENT_BEFORE_LOADONLY, function (Event $event) {
+    /** @var WPLoader $wpLoader */
+    $wpLoader = $event->getOrigin();
+
+    codecept_debug('Running on EVENT_BEFORE_LOADONLY');
+
+    // Interact with the WordPress installation, its filesystem and database.
+    $installation = $wpLoader->getInstallation();
+    $pluginsDir = $installation->getPluginsDir();
+    $db = $installation->getDb();
+    $db->import(codecept_data_dir('some-dump.sql'));
+
+    // Use the PreloadFilters class to hook on WordPress actions and filters.
+    PreloadFilters::addFilter('init', fn() => update_option('some_option', 'some_value'));
+    PreloadFilters::addFilter('pre_option_some_option', fn() => 'some_value');
+});
+
+
EVENT_AFTER_LOADONLY
+

This event fires after WordPress is loaded by the WPLoader module when loadOnly is set to true.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+

At this point, WordPress has been loaded. +You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins.

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPLoader;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPLoader::EVENT_AFTER_LOADONLY, function (Event $event) {
+    /** @var WPLoader $wpLoader */
+    $wpLoader = $event->getOrigin();
+
+    codecept_debug('Running on EVENT_AFTER_LOADONLY');
+
+    // Interact with the WordPress installation, its filesystem and database.    
+    $installation = $wpLoader->getInstallation();
+    $pluginsDir = $installation->getPluginsDir();
+    $db = $installation->getDb();
+    $db->import(codecept_data_dir('some-dump.sql'));
+
+    // Use WordPress functions and classes.
+    update_option('some_option', 'some_value');
+});
+
+
EVENT_BEFORE_INSTALL
+

This event fires before WordPress is installed by the WPLoader module when loadOnly is set to false.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+

WordPress is not loaded yet, so you cannot use functions or classes defined by WordPress, themes or plugins here.
+You can interact with the WordPress installation and use the lucatume\WPBrowser\WordPress\PreloadFilters class to +hook on actions and filters that will be fired by WordPress once loaded.

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPLoader;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPLoader::EVENT_BEFORE_INSTALL, function (Event $event) {
+    /** @var WPLoader $wpLoader */
+    $wpLoader = $event->getOrigin();
+
+    codecept_debug('Running on EVENT_BEFORE_INSTALL');
+
+    // Interact with the WordPress installation, its filesystem and database.
+    $installation = $wpLoader->getInstallation();
+    $pluginsDir = $installation->getPluginsDir();
+    $db = $installation->getDb();
+    $db->import(codecept_data_dir('some-dump.sql'));
+
+    // Use the PreloadFilters class to hook on WordPress actions and filters.
+    PreloadFilters::addFilter('init', fn() => update_option('some_option', 'some_value'));
+    PreloadFilters::addFilter('pre_option_some_option', fn() => 'some_value');
+});
+
+
EVENT_AFTER_INSTALL
+

This event fires after WordPress is installed by the WPLoader module when loadOnly is set to false.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+

At this point, WordPress has been installed and loaded. +You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins. +This event fires before dump files specified in the dump configuration parameter of the WPLoader module are +imported.

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPLoader;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPLoader::EVENT_AFTER_INSTALL, function (Event $event) {
+    /** @var WPLoader $wpLoader */
+    $wpLoader = $event->getOrigin();
+
+    codecept_debug('Running on EVENT_AFTER_INSTALL');
+
+    // Interact with the WordPress installation, its filesystem and database.    
+    $installation = $wpLoader->getInstallation();
+    $pluginsDir = $installation->getPluginsDir();
+    $db = $installation->getDb();
+    $db->import(codecept_data_dir('some-dump.sql'));
+
+    // Use WordPress functions and classes.    
+    update_option('some_option', 'some_value');
+});
+
+
EVENT_AFTER_INSTALL
+

This event fires after WordPress is installed by the WPLoader module when loadOnly is set to false.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+

At this point, WordPress has been installed and loaded. +You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins.

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPLoader;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPLoader::EVENT_AFTER_INSTALL, function (Event $event) {
+    /** @var WPLoader $wpLoader */
+    $wpLoader = $event->getOrigin();
+
+    codecept_debug('Running on EVENT_AFTER_INSTALL');
+
+    // Interact with the WordPress installation, its filesystem and database.    
+    $installation = $wpLoader->getInstallation();
+    $pluginsDir = $installation->getPluginsDir();
+    $db = $installation->getDb();
+    $db->import(codecept_data_dir('some-dump.sql'));
+
+    // Use WordPress functions and classes.
+    update_option('some_option', 'some_value');
+});
+
+
EVENT_AFTER_BOOTSTRAP
+

This event fires after the WPLoader module has finished bootstrapping the WordPress installation and dump files +specified in the dump configuration parameter of the WPLoader module are imported.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+

You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins.

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPLoader;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPLoader::EVENT_AFTER_BOOTSTRAP, function (Event $event) {
+    /** @var WPLoader $wpLoader */
+    $wpLoader = $event->getOrigin();
+
+    codecept_debug('Running on EVENT_AFTER_BOOTSTRAP');
+
+    // Interact with the WordPress installation, its filesystem and database.    
+    $installation = $wpLoader->getInstallation();
+    $pluginsDir = $installation->getPluginsDir();
+    $db = $installation->getDb();
+    $db->import(codecept_data_dir('some-dump.sql'));
+
+    // Use WordPress functions and classes.
+    update_option('some_option', 'some_value');
+});
+
+

Events dispatched by the WPDb module

+
EVENT_BEFORE_SUITE
+

This event fires after the WPDb module has run its _beforeSuite method.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+

At this point the module has connected to the database, cleaned up and populated the database with the dump files.

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPDb;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPDb::EVENT_BEFORE_SUITE, function (Event $event) {
+    /** @var WPDb $wpDb */
+    $wpDb = $event->getOrigin();    
+
+    codecept_debug('Running on EVENT_BEFORE_SUIT
+    E');
+});
+
+
EVENT_BEFORE_INITIALIZE
+

This event fires before the WPDb module initializes.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Module\WPDb;
+use lucatume\WPBrowser\Events\Event;
+
+Dispatcher::addListener(WPDb::EVENT_BEFORE_INITIALIZE, function (Event $event) {
+    /** @var WPDb $wpDb */
+    $wpDb = $event->getOrigin();    
+
+    codecept_debug('Running on EVENT_BEFORE_INITIALIZE');
+});
+
+
EVENT_AFTER_INITIALIZE
+

This event fires after the WPDb module has initialized.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;  
+use lucatume\WPBrowser\Module\WPDb;  
+use lucatume\WPBrowser\Events\Event;  
+
+Dispatcher::addListener(WPDb::EVENT_AFTER_INITIALIZE, function (Event $event) {
+    /** @var WPDb $wpDb */
+    $wpDb = $event->getOrigin();    
+
+    codecept_debug('Running on EVENT_AFTER_INITIALIZE');
+});
+
+
EVENT_AFTER_DB_PREPARE
+

This event fires after the WPDb module has prepared the database setting up some default values for +quality-of-life improvements.

+

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;  
+use lucatume\WPBrowser\Module\WPDb;  
+use lucatume\WPBrowser\Events\Event;  
+
+Dispatcher::addListener(WPDb::EVENT_AFTER_DB_PREPARE, function (Event $event) {
+    /** @var WPDb $wpDb */
+    $wpDb = $event->getOrigin();    
+
+    codecept_debug('Running on EVENT_AFTER_DB_PREPARE');
+});
+
+

Dispatching custom events

+

You can use the Dispatcher::dispatch method to dispatch and subscribe to custom events:

+
<?php
+
+use lucatume\WPBrowser\Events\Dispatcher;
+use lucatume\WPBrowser\Events\Event;  
+
+Dispatcher::dispatch('my-event', 'my-origin', ['foo' => 'bar']);
+
+// Some other code...
+Dispatcher::addListener('my-event', function (Event $event) {
+    $origin = $event->getOrigin();
+    $foo = $event->get('foo');
+    codecept_debug('Running on my custom event');
+});
+
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/assets/external/fonts.googleapis.com/css.49ea35f2.css b/assets/external/fonts.googleapis.com/css.49ea35f2.css new file mode 100644 index 000000000..8187a642b --- /dev/null +++ b/assets/external/fonts.googleapis.com/css.49ea35f2.css @@ -0,0 +1,594 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc3CsTKlA.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc-CsTKlA.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc2CsTKlA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc5CsTKlA.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc1CsTKlA.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc0CsTKlA.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc6CsQ.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xFIzIFKw.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xMIzIFKw.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xEIzIFKw.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xLIzIFKw.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xHIzIFKw.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xGIzIFKw.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xIIzI.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic3CsTKlA.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic-CsTKlA.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic2CsTKlA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic5CsTKlA.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic1CsTKlA.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic0CsTKlA.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic6CsQ.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCRc4EsA.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fABc4EsA.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCBc4EsA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBxc4EsA.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCxc4EsA.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBBc4.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCRc4EsA.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfABc4EsA.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCBc4EsA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBxc4EsA.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCxc4EsA.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfChc4EsA.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBBc4.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEluUlYIw.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEn-UlYIw.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEmOUlYIw.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtElOUlYIw.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEleUlYIw.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEm-Ul.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEluUlYIw.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEn-UlYIw.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEmOUlYIw.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtElOUlYIw.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEleUlYIw.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto Mono'; + font-style: italic; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEm-Ul.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSV0mf0h.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSx0mf0h.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSt0mf0h.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSd0mf0h.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSZ0mf0h.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0mQ.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSV0mf0h.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSx0mf0h.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSt0mf0h.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSd0mf0h.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSZ0mf0h.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 700; + font-display: fallback; + src: url(../fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0mQ.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc-CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc-CsTKlA.woff2 new file mode 100644 index 000000000..943c5a0a8 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc-CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc0CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc0CsTKlA.woff2 new file mode 100644 index 000000000..2bfc2cee9 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc0CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc1CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc1CsTKlA.woff2 new file mode 100644 index 000000000..b2391b928 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc1CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc2CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc2CsTKlA.woff2 new file mode 100644 index 000000000..a4699c78c Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc2CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc3CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc3CsTKlA.woff2 new file mode 100644 index 000000000..bfcc76fab Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc3CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc5CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc5CsTKlA.woff2 new file mode 100644 index 000000000..d4ec18906 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc5CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc6CsQ.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc6CsQ.woff2 new file mode 100644 index 000000000..22c57b015 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc6CsQ.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic-CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic-CsTKlA.woff2 new file mode 100644 index 000000000..d2f30b58a Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic-CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic0CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic0CsTKlA.woff2 new file mode 100644 index 000000000..c88b8aeae Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic0CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic1CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic1CsTKlA.woff2 new file mode 100644 index 000000000..6363b1c7e Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic1CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic2CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic2CsTKlA.woff2 new file mode 100644 index 000000000..dd5a4a2e5 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic2CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic3CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic3CsTKlA.woff2 new file mode 100644 index 000000000..6abf54d06 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic3CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic5CsTKlA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic5CsTKlA.woff2 new file mode 100644 index 000000000..c8091bc97 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic5CsTKlA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic6CsQ.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic6CsQ.woff2 new file mode 100644 index 000000000..a56a6edef Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic6CsQ.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xEIzIFKw.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xEIzIFKw.woff2 new file mode 100644 index 000000000..508baefbc Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xEIzIFKw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xFIzIFKw.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xFIzIFKw.woff2 new file mode 100644 index 000000000..9213da013 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xFIzIFKw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xGIzIFKw.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xGIzIFKw.woff2 new file mode 100644 index 000000000..ef920e5ae Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xGIzIFKw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xHIzIFKw.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xHIzIFKw.woff2 new file mode 100644 index 000000000..9a378af0c Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xHIzIFKw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xIIzI.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xIIzI.woff2 new file mode 100644 index 000000000..e1b7a79f9 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xIIzI.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xLIzIFKw.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xLIzIFKw.woff2 new file mode 100644 index 000000000..e0d3c4356 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xLIzIFKw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xMIzIFKw.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xMIzIFKw.woff2 new file mode 100644 index 000000000..dd587a2bc Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xMIzIFKw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fABc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fABc4EsA.woff2 new file mode 100644 index 000000000..9d7fb7f87 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fABc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBBc4.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBBc4.woff2 new file mode 100644 index 000000000..60681387e Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBBc4.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBxc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBxc4EsA.woff2 new file mode 100644 index 000000000..b289f0029 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBxc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCBc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCBc4EsA.woff2 new file mode 100644 index 000000000..87711c048 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCBc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCRc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCRc4EsA.woff2 new file mode 100644 index 000000000..0f6e60b8e Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCRc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2 new file mode 100644 index 000000000..91231c9c4 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCxc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCxc4EsA.woff2 new file mode 100644 index 000000000..c00998785 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCxc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfABc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfABc4EsA.woff2 new file mode 100644 index 000000000..1bb7737cd Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfABc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBBc4.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBBc4.woff2 new file mode 100644 index 000000000..771fbeccc Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBBc4.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBxc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBxc4EsA.woff2 new file mode 100644 index 000000000..cb9bfa71f Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBxc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCBc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCBc4EsA.woff2 new file mode 100644 index 000000000..a0d68e2b4 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCBc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCRc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCRc4EsA.woff2 new file mode 100644 index 000000000..639955285 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCRc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfChc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfChc4EsA.woff2 new file mode 100644 index 000000000..94ab5fb01 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfChc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCxc4EsA.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCxc4EsA.woff2 new file mode 100644 index 000000000..3c4501118 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCxc4EsA.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2 new file mode 100644 index 000000000..fc71d944a Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 new file mode 100644 index 000000000..020729ef8 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2 new file mode 100644 index 000000000..47da36299 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2 new file mode 100644 index 000000000..22ddee9c9 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2 new file mode 100644 index 000000000..8a8de615e Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2 new file mode 100644 index 000000000..6284d2e3b Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2 b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2 new file mode 100644 index 000000000..72ce0e984 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSV0mf0h.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSV0mf0h.woff2 new file mode 100644 index 000000000..022274d4c Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSV0mf0h.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSZ0mf0h.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSZ0mf0h.woff2 new file mode 100644 index 000000000..48edd1b09 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSZ0mf0h.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSd0mf0h.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSd0mf0h.woff2 new file mode 100644 index 000000000..cb41535eb Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSd0mf0h.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0mQ.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0mQ.woff2 new file mode 100644 index 000000000..1d988a3f4 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0mQ.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSt0mf0h.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSt0mf0h.woff2 new file mode 100644 index 000000000..11e6a46a4 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSt0mf0h.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSx0mf0h.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSx0mf0h.woff2 new file mode 100644 index 000000000..50fb8e711 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSx0mf0h.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtElOUlYIw.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtElOUlYIw.woff2 new file mode 100644 index 000000000..1f1c97fec Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtElOUlYIw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEleUlYIw.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEleUlYIw.woff2 new file mode 100644 index 000000000..162300519 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEleUlYIw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEluUlYIw.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEluUlYIw.woff2 new file mode 100644 index 000000000..6f232c38a Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEluUlYIw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEm-Ul.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEm-Ul.woff2 new file mode 100644 index 000000000..a3e5aef7c Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEm-Ul.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEmOUlYIw.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEmOUlYIw.woff2 new file mode 100644 index 000000000..f73f27d6e Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEmOUlYIw.woff2 differ diff --git a/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEn-UlYIw.woff2 b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEn-UlYIw.woff2 new file mode 100644 index 000000000..135d06e00 Binary files /dev/null and b/assets/external/fonts.gstatic.com/s/robotomono/v23/L0xdDF4xlVMF-BfR8bXMIjhOsXG-q2oeuFoqFrlnAIe2Imhk1T8rbociImtEn-UlYIw.woff2 differ diff --git a/assets/external/unpkg.com/mermaid@10/dist/mermaid.min.js b/assets/external/unpkg.com/mermaid@10/dist/mermaid.min.js new file mode 100644 index 000000000..3dce007ac --- /dev/null +++ b/assets/external/unpkg.com/mermaid@10/dist/mermaid.min.js @@ -0,0 +1,2029 @@ +(function(JM,Ag){typeof exports=="object"&&typeof module<"u"?module.exports=Ag():typeof define=="function"&&define.amd?define(Ag):(JM=typeof globalThis<"u"?globalThis:JM||self,JM.mermaid=Ag())})(this,function(){var FWe,RWe;"use strict";function JM(i){for(var s=[],u=1;u=Pe?Fe:""+Array(Pe+1-Ie.length).join(je)+Fe},be={s:pe,z:function(Fe){var Pe=-Fe.utcOffset(),je=Math.abs(Pe),Ie=Math.floor(je/60),Se=je%60;return(Pe<=0?"+":"-")+pe(Ie,2,"0")+":"+pe(Se,2,"0")},m:function Fe(Pe,je){if(Pe.date()1)return Fe(ke[0])}else{var Ke=Pe.name;ne[Ke]=Pe,Se=Ke}return!Ie&&Se&&(ae=Se),Se||!Ie&&ae},ge=function(Fe,Pe){if(de(Fe))return Fe.clone();var je=typeof Pe=="object"?Pe:{};return je.date=Fe,je.args=arguments,new xe(je)},W=be;W.l=X,W.i=de,W.w=function(Fe,Pe){return ge(Fe,{locale:Pe.$L,utc:Pe.$u,x:Pe.$x,$offset:Pe.$offset})};var xe=function(){function Fe(je){this.$L=X(je.locale,null,!0),this.parse(je),this.$x=this.$x||je.x||{},this[se]=!0}var Pe=Fe.prototype;return Pe.parse=function(je){this.$d=function(Ie){var Se=Ie.date,Ce=Ie.utc;if(Se===null)return new Date(NaN);if(W.u(Se))return new Date;if(Se instanceof Date)return new Date(Se);if(typeof Se=="string"&&!/Z$/i.test(Se)){var ke=Se.match(ee);if(ke){var Ke=ke[2]-1||0,Ft=(ke[7]||"0").substring(0,3);return Ce?new Date(Date.UTC(ke[1],Ke,ke[3]||1,ke[4]||0,ke[5]||0,ke[6]||0,Ft)):new Date(ke[1],Ke,ke[3]||1,ke[4]||0,ke[5]||0,ke[6]||0,Ft)}}return new Date(Se)}(je),this.init()},Pe.init=function(){var je=this.$d;this.$y=je.getFullYear(),this.$M=je.getMonth(),this.$D=je.getDate(),this.$W=je.getDay(),this.$H=je.getHours(),this.$m=je.getMinutes(),this.$s=je.getSeconds(),this.$ms=je.getMilliseconds()},Pe.$utils=function(){return W},Pe.isValid=function(){return this.$d.toString()!==K},Pe.isSame=function(je,Ie){var Se=ge(je);return this.startOf(Ie)<=Se&&Se<=this.endOf(Ie)},Pe.isAfter=function(je,Ie){return ge(je){},debug:(...i)=>{},info:(...i)=>{},warn:(...i)=>{},error:(...i)=>{},fatal:(...i)=>{}},fpe=function(i="fatal"){let s=g7.fatal;typeof i=="string"?(i=i.toLowerCase(),i in g7&&(s=g7[i])):typeof i=="number"&&(s=i),Xe.trace=()=>{},Xe.debug=()=>{},Xe.info=()=>{},Xe.warn=()=>{},Xe.error=()=>{},Xe.fatal=()=>{},s<=g7.fatal&&(Xe.fatal=console.error?console.error.bind(console,Lv("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",Lv("FATAL"))),s<=g7.error&&(Xe.error=console.error?console.error.bind(console,Lv("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",Lv("ERROR"))),s<=g7.warn&&(Xe.warn=console.warn?console.warn.bind(console,Lv("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",Lv("WARN"))),s<=g7.info&&(Xe.info=console.info?console.info.bind(console,Lv("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",Lv("INFO"))),s<=g7.debug&&(Xe.debug=console.debug?console.debug.bind(console,Lv("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",Lv("DEBUG"))),s<=g7.trace&&(Xe.trace=console.debug?console.debug.bind(console,Lv("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",Lv("TRACE")))},Lv=i=>`%c${Lg().format("ss.SSS")} : ${i} : `;var p9={};(function(i){Object.defineProperty(i,"__esModule",{value:!0}),i.sanitizeUrl=i.BLANK_URL=void 0;var s=/^([^\w]*)(javascript|data|vbscript)/im,u=/&#(\w+)(^\w|;)?/g,d=/&(newline|tab);/gi,p=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,v=/^.+(:|:)/gim,b=[".","/"];i.BLANK_URL="about:blank";function y(A){return b.indexOf(A[0])>-1}function T(A){var P=A.replace(p,"");return P.replace(u,function(R,F){return String.fromCharCode(F)})}function _(A){if(!A)return i.BLANK_URL;var P=T(A).replace(d,"").replace(p,"").trim();if(!P)return i.BLANK_URL;if(y(P))return P;var R=P.match(v);if(!R)return P;var F=R[0];return s.test(F)?i.BLANK_URL:P}i.sanitizeUrl=_})(p9);function DY(i,s){return i==null||s==null?NaN:is?1:i>=s?0:NaN}function PAt(i,s){return i==null||s==null?NaN:si?1:s>=i?0:NaN}function dpe(i){let s,u,d;i.length!==2?(s=DY,u=(y,T)=>DY(i(y),T),d=(y,T)=>i(y)-T):(s=i===DY||i===PAt?i:BAt,u=i,d=i);function p(y,T,_=0,A=y.length){if(_>>1;u(y[P],T)<0?_=P+1:A=P}while(_>>1;u(y[P],T)<=0?_=P+1:A=P}while(__&&d(y[P-1],T)>-d(y[P],T)?P-1:P}return{left:p,center:b,right:v}}function BAt(){return 0}function FAt(i){return i===null?NaN:+i}const RAt=dpe(DY).right;dpe(FAt).center;const jAt=RAt;class cBe extends Map{constructor(s,u=qAt){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:u}}),s!=null)for(const[d,p]of s)this.set(d,p)}get(s){return super.get(uBe(this,s))}has(s){return super.has(uBe(this,s))}set(s,u){return super.set($At(this,s),u)}delete(s){return super.delete(zAt(this,s))}}function uBe({_intern:i,_key:s},u){const d=s(u);return i.has(d)?i.get(d):u}function $At({_intern:i,_key:s},u){const d=s(u);return i.has(d)?i.get(d):(i.set(d,u),u)}function zAt({_intern:i,_key:s},u){const d=s(u);return i.has(d)&&(u=i.get(d),i.delete(d)),u}function qAt(i){return i!==null&&typeof i=="object"?i.valueOf():i}const HAt=Math.sqrt(50),VAt=Math.sqrt(10),UAt=Math.sqrt(2);function IY(i,s,u){const d=(s-i)/Math.max(0,u),p=Math.floor(Math.log10(d)),v=d/Math.pow(10,p),b=v>=HAt?10:v>=VAt?5:v>=UAt?2:1;let y,T,_;return p<0?(_=Math.pow(10,-p)/b,y=Math.round(i*_),T=Math.round(s*_),y/_s&&--T,_=-_):(_=Math.pow(10,p)*b,y=Math.round(i/_),T=Math.round(s/_),y*_s&&--T),T0))return[];if(i===s)return[i];const d=s=p))return[];const y=v-p+1,T=new Array(y);if(d)if(b<0)for(let _=0;_=d)&&(u=d);else{let d=-1;for(let p of i)(p=s(p,++d,i))!=null&&(u=p)&&(u=p)}return u}function WAt(i,s){let u;if(s===void 0)for(const d of i)d!=null&&(u>d||u===void 0&&d>=d)&&(u=d);else{let d=-1;for(let p of i)(p=s(p,++d,i))!=null&&(u>p||u===void 0&&p>=p)&&(u=p)}return u}function YAt(i,s,u){i=+i,s=+s,u=(p=arguments.length)<2?(s=i,i=0,1):p<3?1:+u;for(var d=-1,p=Math.max(0,Math.ceil((s-i)/u))|0,v=new Array(p);++d+i(s)}function eLt(i,s){return s=Math.max(0,i.bandwidth()-s*2)/2,i.round()&&(s=Math.round(s)),u=>+i(u)+s}function tLt(){return!this.__axis}function hBe(i,s){var u=[],d=null,p=null,v=6,b=6,y=3,T=typeof window<"u"&&window.devicePixelRatio>1?0:.5,_=i===OY||i===NY?-1:1,A=i===NY||i===bpe?"x":"y",P=i===OY||i===mpe?QAt:JAt;function R(F){var j=d??(s.ticks?s.ticks.apply(s,u):s.domain()),K=p??(s.tickFormat?s.tickFormat.apply(s,u):XAt),ee=Math.max(v,0)+y,ie=s.range(),oe=+ie[0]+T,pe=+ie[ie.length-1]+T,be=(s.bandwidth?eLt:ZAt)(s.copy(),T),ae=F.selection?F.selection():F,ne=ae.selectAll(".domain").data([null]),se=ae.selectAll(".tick").data(j,s).order(),de=se.exit(),X=se.enter().append("g").attr("class","tick"),ge=se.select("line"),W=se.select("text");ne=ne.merge(ne.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),se=se.merge(X),ge=ge.merge(X.append("line").attr("stroke","currentColor").attr(A+"2",_*v)),W=W.merge(X.append("text").attr("fill","currentColor").attr(A,_*ee).attr("dy",i===OY?"0em":i===mpe?"0.71em":"0.32em")),F!==ae&&(ne=ne.transition(F),se=se.transition(F),ge=ge.transition(F),W=W.transition(F),de=de.transition(F).attr("opacity",lBe).attr("transform",function(xe){return isFinite(xe=be(xe))?P(xe+T):this.getAttribute("transform")}),X.attr("opacity",lBe).attr("transform",function(xe){var U=this.parentNode.__axis;return P((U&&isFinite(U=U(xe))?U:be(xe))+T)})),de.remove(),ne.attr("d",i===NY||i===bpe?b?"M"+_*b+","+oe+"H"+T+"V"+pe+"H"+_*b:"M"+T+","+oe+"V"+pe:b?"M"+oe+","+_*b+"V"+T+"H"+pe+"V"+_*b:"M"+oe+","+T+"H"+pe),se.attr("opacity",1).attr("transform",function(xe){return P(be(xe)+T)}),ge.attr(A+"2",_*v),W.attr(A,_*ee).text(K),ae.filter(tLt).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",i===bpe?"start":i===NY?"end":"middle"),ae.each(function(){this.__axis=be})}return R.scale=function(F){return arguments.length?(s=F,R):s},R.ticks=function(){return u=Array.from(arguments),R},R.tickArguments=function(F){return arguments.length?(u=F==null?[]:Array.from(F),R):u.slice()},R.tickValues=function(F){return arguments.length?(d=F==null?null:Array.from(F),R):d&&d.slice()},R.tickFormat=function(F){return arguments.length?(p=F,R):p},R.tickSize=function(F){return arguments.length?(v=b=+F,R):v},R.tickSizeInner=function(F){return arguments.length?(v=+F,R):v},R.tickSizeOuter=function(F){return arguments.length?(b=+F,R):b},R.tickPadding=function(F){return arguments.length?(y=+F,R):y},R.offset=function(F){return arguments.length?(T=+F,R):T},R}function nLt(i){return hBe(OY,i)}function rLt(i){return hBe(mpe,i)}var iLt={value:()=>{}};function fBe(){for(var i=0,s=arguments.length,u={},d;i=0&&(d=u.slice(p+1),u=u.slice(0,p)),u&&!s.hasOwnProperty(u))throw new Error("unknown type: "+u);return{type:u,name:d}})}PY.prototype=fBe.prototype={constructor:PY,on:function(i,s){var u=this._,d=sLt(i+"",u),p,v=-1,b=d.length;if(arguments.length<2){for(;++v0)for(var u=new Array(p),d=0,p,v;d=0&&(s=i.slice(0,u))!=="xmlns"&&(i=i.slice(u+1)),gBe.hasOwnProperty(s)?{space:gBe[s],local:i}:i}function oLt(i){return function(){var s=this.ownerDocument,u=this.namespaceURI;return u===vpe&&s.documentElement.namespaceURI===vpe?s.createElement(i):s.createElementNS(u,i)}}function cLt(i){return function(){return this.ownerDocument.createElementNS(i.space,i.local)}}function pBe(i){var s=BY(i);return(s.local?cLt:oLt)(s)}function uLt(){}function wpe(i){return i==null?uLt:function(){return this.querySelector(i)}}function lLt(i){typeof i!="function"&&(i=wpe(i));for(var s=this._groups,u=s.length,d=new Array(u),p=0;p=pe&&(pe=oe+1);!(ae=ee[pe])&&++pe=0;)(b=d[p])&&(v&&b.compareDocumentPosition(v)^4&&v.parentNode.insertBefore(b,v),v=b);return this}function NLt(i){i||(i=PLt);function s(P,R){return P&&R?i(P.__data__,R.__data__):!P-!R}for(var u=this._groups,d=u.length,p=new Array(d),v=0;vs?1:i>=s?0:NaN}function BLt(){var i=arguments[0];return arguments[0]=this,i.apply(null,arguments),this}function FLt(){return Array.from(this)}function RLt(){for(var i=this._groups,s=0,u=i.length;s1?this.each((s==null?YLt:typeof s=="function"?QLt:XLt)(i,s,u??"")):ZM(this.node(),i)}function ZM(i,s){return i.style.getPropertyValue(s)||xBe(i).getComputedStyle(i,null).getPropertyValue(s)}function ZLt(i){return function(){delete this[i]}}function eMt(i,s){return function(){this[i]=s}}function tMt(i,s){return function(){var u=s.apply(this,arguments);u==null?delete this[i]:this[i]=u}}function nMt(i,s){return arguments.length>1?this.each((s==null?ZLt:typeof s=="function"?tMt:eMt)(i,s)):this.node()[i]}function kBe(i){return i.trim().split(/^|\s+/)}function ype(i){return i.classList||new EBe(i)}function EBe(i){this._node=i,this._names=kBe(i.getAttribute("class")||"")}EBe.prototype={add:function(i){var s=this._names.indexOf(i);s<0&&(this._names.push(i),this._node.setAttribute("class",this._names.join(" ")))},remove:function(i){var s=this._names.indexOf(i);s>=0&&(this._names.splice(s,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(i){return this._names.indexOf(i)>=0}};function TBe(i,s){for(var u=ype(i),d=-1,p=s.length;++d=0&&(u=s.slice(d+1),s=s.slice(0,d)),{type:s,name:u}})}function MMt(i){return function(){var s=this.__on;if(s){for(var u=0,d=-1,p=s.length,v;u>8&15|s>>4&240,s>>4&15|s&240,(s&15)<<4|s&15,1):u===8?$Y(s>>24&255,s>>16&255,s>>8&255,(s&255)/255):u===4?$Y(s>>12&15|s>>8&240,s>>8&15|s>>4&240,s>>4&15|s&240,((s&15)<<4|s&15)/255):null):(s=jMt.exec(i))?new Mg(s[1],s[2],s[3],1):(s=$Mt.exec(i))?new Mg(s[1]*255/100,s[2]*255/100,s[3]*255/100,1):(s=zMt.exec(i))?$Y(s[1],s[2],s[3],s[4]):(s=qMt.exec(i))?$Y(s[1]*255/100,s[2]*255/100,s[3]*255/100,s[4]):(s=HMt.exec(i))?PBe(s[1],s[2]/100,s[3]/100,1):(s=VMt.exec(i))?PBe(s[1],s[2]/100,s[3]/100,s[4]):ABe.hasOwnProperty(i)?DBe(ABe[i]):i==="transparent"?new Mg(NaN,NaN,NaN,0):null}function DBe(i){return new Mg(i>>16&255,i>>8&255,i&255,1)}function $Y(i,s,u,d){return d<=0&&(i=s=u=NaN),new Mg(i,s,u,d)}function IBe(i){return i instanceof fC||(i=dC(i)),i?(i=i.rgb(),new Mg(i.r,i.g,i.b,i.opacity)):new Mg}function kpe(i,s,u,d){return arguments.length===1?IBe(i):new Mg(i,s,u,d??1)}function Mg(i,s,u,d){this.r=+i,this.g=+s,this.b=+u,this.opacity=+d}wF(Mg,kpe,RY(fC,{brighter(i){return i=i==null?jY:Math.pow(jY,i),new Mg(this.r*i,this.g*i,this.b*i,this.opacity)},darker(i){return i=i==null?yF:Math.pow(yF,i),new Mg(this.r*i,this.g*i,this.b*i,this.opacity)},rgb(){return this},clamp(){return new Mg(gC(this.r),gC(this.g),gC(this.b),zY(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:OBe,formatHex:OBe,formatHex8:KMt,formatRgb:NBe,toString:NBe}));function OBe(){return`#${pC(this.r)}${pC(this.g)}${pC(this.b)}`}function KMt(){return`#${pC(this.r)}${pC(this.g)}${pC(this.b)}${pC((isNaN(this.opacity)?1:this.opacity)*255)}`}function NBe(){const i=zY(this.opacity);return`${i===1?"rgb(":"rgba("}${gC(this.r)}, ${gC(this.g)}, ${gC(this.b)}${i===1?")":`, ${i})`}`}function zY(i){return isNaN(i)?1:Math.max(0,Math.min(1,i))}function gC(i){return Math.max(0,Math.min(255,Math.round(i)||0))}function pC(i){return i=gC(i),(i<16?"0":"")+i.toString(16)}function PBe(i,s,u,d){return d<=0?i=s=u=NaN:u<=0||u>=1?i=s=NaN:s<=0&&(i=NaN),new A3(i,s,u,d)}function BBe(i){if(i instanceof A3)return new A3(i.h,i.s,i.l,i.opacity);if(i instanceof fC||(i=dC(i)),!i)return new A3;if(i instanceof A3)return i;i=i.rgb();var s=i.r/255,u=i.g/255,d=i.b/255,p=Math.min(s,u,d),v=Math.max(s,u,d),b=NaN,y=v-p,T=(v+p)/2;return y?(s===v?b=(u-d)/y+(u0&&T<1?0:b,new A3(b,y,T,i.opacity)}function WMt(i,s,u,d){return arguments.length===1?BBe(i):new A3(i,s,u,d??1)}function A3(i,s,u,d){this.h=+i,this.s=+s,this.l=+u,this.opacity=+d}wF(A3,WMt,RY(fC,{brighter(i){return i=i==null?jY:Math.pow(jY,i),new A3(this.h,this.s,this.l*i,this.opacity)},darker(i){return i=i==null?yF:Math.pow(yF,i),new A3(this.h,this.s,this.l*i,this.opacity)},rgb(){var i=this.h%360+(this.h<0)*360,s=isNaN(i)||isNaN(this.s)?0:this.s,u=this.l,d=u+(u<.5?u:1-u)*s,p=2*u-d;return new Mg(Epe(i>=240?i-240:i+120,p,d),Epe(i,p,d),Epe(i<120?i+240:i-120,p,d),this.opacity)},clamp(){return new A3(FBe(this.h),qY(this.s),qY(this.l),zY(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(){const i=zY(this.opacity);return`${i===1?"hsl(":"hsla("}${FBe(this.h)}, ${qY(this.s)*100}%, ${qY(this.l)*100}%${i===1?")":`, ${i})`}`}}));function FBe(i){return i=(i||0)%360,i<0?i+360:i}function qY(i){return Math.max(0,Math.min(1,i||0))}function Epe(i,s,u){return(i<60?s+(u-s)*i/60:i<180?u:i<240?s+(u-s)*(240-i)/60:s)*255}const YMt=Math.PI/180,XMt=180/Math.PI,HY=18,RBe=.96422,jBe=1,$Be=.82521,zBe=4/29,tD=6/29,qBe=3*tD*tD,QMt=tD*tD*tD;function HBe(i){if(i instanceof j4)return new j4(i.l,i.a,i.b,i.opacity);if(i instanceof p7)return VBe(i);i instanceof Mg||(i=IBe(i));var s=_pe(i.r),u=_pe(i.g),d=_pe(i.b),p=Tpe((.2225045*s+.7168786*u+.0606169*d)/jBe),v,b;return s===u&&u===d?v=b=p:(v=Tpe((.4360747*s+.3850649*u+.1430804*d)/RBe),b=Tpe((.0139322*s+.0971045*u+.7141733*d)/$Be)),new j4(116*p-16,500*(v-p),200*(p-b),i.opacity)}function JMt(i,s,u,d){return arguments.length===1?HBe(i):new j4(i,s,u,d??1)}function j4(i,s,u,d){this.l=+i,this.a=+s,this.b=+u,this.opacity=+d}wF(j4,JMt,RY(fC,{brighter(i){return new j4(this.l+HY*(i??1),this.a,this.b,this.opacity)},darker(i){return new j4(this.l-HY*(i??1),this.a,this.b,this.opacity)},rgb(){var i=(this.l+16)/116,s=isNaN(this.a)?i:i+this.a/500,u=isNaN(this.b)?i:i-this.b/200;return s=RBe*Cpe(s),i=jBe*Cpe(i),u=$Be*Cpe(u),new Mg(Spe(3.1338561*s-1.6168667*i-.4906146*u),Spe(-.9787684*s+1.9161415*i+.033454*u),Spe(.0719453*s-.2289914*i+1.4052427*u),this.opacity)}}));function Tpe(i){return i>QMt?Math.pow(i,1/3):i/qBe+zBe}function Cpe(i){return i>tD?i*i*i:qBe*(i-zBe)}function Spe(i){return 255*(i<=.0031308?12.92*i:1.055*Math.pow(i,1/2.4)-.055)}function _pe(i){return(i/=255)<=.04045?i/12.92:Math.pow((i+.055)/1.055,2.4)}function ZMt(i){if(i instanceof p7)return new p7(i.h,i.c,i.l,i.opacity);if(i instanceof j4||(i=HBe(i)),i.a===0&&i.b===0)return new p7(NaN,0()=>i;function UBe(i,s){return function(u){return i+u*s}}function eDt(i,s,u){return i=Math.pow(i,u),s=Math.pow(s,u)-i,u=1/u,function(d){return Math.pow(i+d*s,u)}}function tDt(i,s){var u=s-i;return u?UBe(i,u>180||u<-180?u-360*Math.round(u/360):u):VY(isNaN(i)?s:i)}function nDt(i){return(i=+i)==1?kF:function(s,u){return u-s?eDt(s,u,i):VY(isNaN(s)?u:s)}}function kF(i,s){var u=s-i;return u?UBe(i,u):VY(isNaN(i)?s:i)}const UY=function i(s){var u=nDt(s);function d(p,v){var b=u((p=kpe(p)).r,(v=kpe(v)).r),y=u(p.g,v.g),T=u(p.b,v.b),_=kF(p.opacity,v.opacity);return function(A){return p.r=b(A),p.g=y(A),p.b=T(A),p.opacity=_(A),p+""}}return d.gamma=i,d}(1);function rDt(i,s){s||(s=[]);var u=i?Math.min(s.length,i.length):0,d=s.slice(),p;return function(v){for(p=0;pu&&(v=s.slice(u,v),y[b]?y[b]+=v:y[++b]=v),(d=d[0])===(p=p[0])?y[b]?y[b]+=p:y[++b]=p:(y[++b]=null,T.push({i:b,x:L3(d,p)})),u=Mpe.lastIndex;return u180?A+=360:A-_>180&&(_+=360),R.push({i:P.push(p(P)+"rotate(",null,d)-2,x:L3(_,A)})):A&&P.push(p(P)+"rotate("+A+d)}function y(_,A,P,R){_!==A?R.push({i:P.push(p(P)+"skewX(",null,d)-2,x:L3(_,A)}):A&&P.push(p(P)+"skewX("+A+d)}function T(_,A,P,R,F,j){if(_!==P||A!==R){var K=F.push(p(F)+"scale(",null,",",null,")");j.push({i:K-4,x:L3(_,P)},{i:K-2,x:L3(A,R)})}else(P!==1||R!==1)&&F.push(p(F)+"scale("+P+","+R+")")}return function(_,A){var P=[],R=[];return _=i(_),A=i(A),v(_.translateX,_.translateY,A.translateX,A.translateY,P,R),b(_.rotate,A.rotate,P,R),y(_.skewX,A.skewX,P,R),T(_.scaleX,_.scaleY,A.scaleX,A.scaleY,P,R),_=A=null,function(F){for(var j=-1,K=R.length,ee;++j=0&&i._call.call(void 0,s),i=i._next;--nD}function ZBe(){bC=(WY=SF.now())+YY,nD=EF=0;try{vDt()}finally{nD=0,yDt(),bC=0}}function wDt(){var i=SF.now(),s=i-WY;s>XBe&&(YY-=s,WY=i)}function yDt(){for(var i,s=KY,u,d=1/0;s;)s._call?(d>s._time&&(d=s._time),i=s,s=s._next):(u=s._next,s._next=null,s=i?i._next=u:KY=u);CF=i,Npe(d)}function Npe(i){if(!nD){EF&&(EF=clearTimeout(EF));var s=i-bC;s>24?(i<1/0&&(EF=setTimeout(ZBe,i-SF.now()-YY)),TF&&(TF=clearInterval(TF))):(TF||(WY=SF.now(),TF=setInterval(wDt,XBe)),nD=1,QBe(ZBe))}}function eFe(i,s,u){var d=new XY;return s=s==null?0:+s,d.restart(p=>{d.stop(),i(p+s)},s,u),d}var xDt=fBe("start","end","cancel","interrupt"),kDt=[],tFe=0,nFe=1,Ppe=2,QY=3,rFe=4,Bpe=5,JY=6;function ZY(i,s,u,d,p,v){var b=i.__transition;if(!b)i.__transition={};else if(u in b)return;EDt(i,u,{name:s,index:d,group:p,on:xDt,tween:kDt,time:v.time,delay:v.delay,duration:v.duration,ease:v.ease,timer:null,state:tFe})}function Fpe(i,s){var u=M3(i,s);if(u.state>tFe)throw new Error("too late; already scheduled");return u}function $4(i,s){var u=M3(i,s);if(u.state>QY)throw new Error("too late; already running");return u}function M3(i,s){var u=i.__transition;if(!u||!(u=u[s]))throw new Error("transition not found");return u}function EDt(i,s,u){var d=i.__transition,p;d[s]=u,u.timer=JBe(v,0,u.time);function v(_){u.state=nFe,u.timer.restart(b,u.delay,u.time),u.delay<=_&&b(_-u.delay)}function b(_){var A,P,R,F;if(u.state!==nFe)return T();for(A in d)if(F=d[A],F.name===u.name){if(F.state===QY)return eFe(b);F.state===rFe?(F.state=JY,F.timer.stop(),F.on.call("interrupt",i,i.__data__,F.index,F.group),delete d[A]):+APpe&&d.state=0&&(s=s.slice(0,u)),!s||s==="start"})}function eIt(i,s,u){var d,p,v=ZDt(s)?Fpe:$4;return function(){var b=v(this,i),y=b.on;y!==d&&(p=(d=y).copy()).on(s,u),b.on=p}}function tIt(i,s){var u=this._id;return arguments.length<2?M3(this.node(),u).on.on(i):this.each(eIt(u,i,s))}function nIt(i){return function(){var s=this.parentNode;for(var u in this.__transition)if(+u!==i)return;s&&s.removeChild(this)}}function rIt(){return this.on("end.remove",nIt(this._id))}function iIt(i){var s=this._name,u=this._id;typeof i!="function"&&(i=wpe(i));for(var d=this._groups,p=d.length,v=new Array(p),b=0;b=0))throw new Error(`invalid digits: ${i}`);if(s>15)return oFe;const u=10**s;return function(d){this._+=d[0];for(let p=1,v=d.length;pmC)if(!(Math.abs(P*T-_*A)>mC)||!v)this._append`L${this._x1=s},${this._y1=u}`;else{let F=d-b,j=p-y,K=T*T+_*_,ee=F*F+j*j,ie=Math.sqrt(K),oe=Math.sqrt(R),pe=v*Math.tan((jpe-Math.acos((K+R-ee)/(2*ie*oe)))/2),be=pe/oe,ae=pe/ie;Math.abs(be-1)>mC&&this._append`L${s+be*A},${u+be*P}`,this._append`A${v},${v},0,0,${+(P*F>A*j)},${this._x1=s+ae*T},${this._y1=u+ae*_}`}}arc(s,u,d,p,v,b){if(s=+s,u=+u,d=+d,b=!!b,d<0)throw new Error(`negative radius: ${d}`);let y=d*Math.cos(p),T=d*Math.sin(p),_=s+y,A=u+T,P=1^b,R=b?p-v:v-p;this._x1===null?this._append`M${_},${A}`:(Math.abs(this._x1-_)>mC||Math.abs(this._y1-A)>mC)&&this._append`L${_},${A}`,d&&(R<0&&(R=R%$pe+$pe),R>LIt?this._append`A${d},${d},0,1,${P},${s-y},${u-T}A${d},${d},0,1,${P},${this._x1=_},${this._y1=A}`:R>mC&&this._append`A${d},${d},0,${+(R>=jpe)},${P},${this._x1=s+d*Math.cos(v)},${this._y1=u+d*Math.sin(v)}`)}rect(s,u,d,p){this._append`M${this._x0=this._x1=+s},${this._y0=this._y1=+u}h${d=+d}v${+p}h${-d}Z`}toString(){return this._}};function IIt(i){if(!i.ok)throw new Error(i.status+" "+i.statusText);return i.text()}function OIt(i,s){return fetch(i,s).then(IIt)}function NIt(i){return(s,u)=>OIt(s,u).then(d=>new DOMParser().parseFromString(d,i))}var PIt=NIt("image/svg+xml");function BIt(i){return Math.abs(i=Math.round(i))>=1e21?i.toLocaleString("en").replace(/,/g,""):i.toString(10)}function eX(i,s){if((u=(i=s?i.toExponential(s-1):i.toExponential()).indexOf("e"))<0)return null;var u,d=i.slice(0,u);return[d.length>1?d[0]+d.slice(2):d,+i.slice(u+1)]}function rD(i){return i=eX(Math.abs(i)),i?i[1]:NaN}function FIt(i,s){return function(u,d){for(var p=u.length,v=[],b=0,y=i[0],T=0;p>0&&y>0&&(T+y+1>d&&(y=Math.max(1,d-T)),v.push(u.substring(p-=y,p+y)),!((T+=y+1)>d));)y=i[b=(b+1)%i.length];return v.reverse().join(s)}}function RIt(i){return function(s){return s.replace(/[0-9]/g,function(u){return i[+u]})}}var jIt=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function tX(i){if(!(s=jIt.exec(i)))throw new Error("invalid format: "+i);var s;return new zpe({fill:s[1],align:s[2],sign:s[3],symbol:s[4],zero:s[5],width:s[6],comma:s[7],precision:s[8]&&s[8].slice(1),trim:s[9],type:s[10]})}tX.prototype=zpe.prototype;function zpe(i){this.fill=i.fill===void 0?" ":i.fill+"",this.align=i.align===void 0?">":i.align+"",this.sign=i.sign===void 0?"-":i.sign+"",this.symbol=i.symbol===void 0?"":i.symbol+"",this.zero=!!i.zero,this.width=i.width===void 0?void 0:+i.width,this.comma=!!i.comma,this.precision=i.precision===void 0?void 0:+i.precision,this.trim=!!i.trim,this.type=i.type===void 0?"":i.type+""}zpe.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 $It(i){e:for(var s=i.length,u=1,d=-1,p;u0&&(d=0);break}return d>0?i.slice(0,d)+i.slice(p+1):i}var cFe;function zIt(i,s){var u=eX(i,s);if(!u)return i+"";var d=u[0],p=u[1],v=p-(cFe=Math.max(-8,Math.min(8,Math.floor(p/3)))*3)+1,b=d.length;return v===b?d:v>b?d+new Array(v-b+1).join("0"):v>0?d.slice(0,v)+"."+d.slice(v):"0."+new Array(1-v).join("0")+eX(i,Math.max(0,s+v-1))[0]}function uFe(i,s){var u=eX(i,s);if(!u)return i+"";var d=u[0],p=u[1];return p<0?"0."+new Array(-p).join("0")+d:d.length>p+1?d.slice(0,p+1)+"."+d.slice(p+1):d+new Array(p-d.length+2).join("0")}const lFe={"%":(i,s)=>(i*100).toFixed(s),b:i=>Math.round(i).toString(2),c:i=>i+"",d:BIt,e:(i,s)=>i.toExponential(s),f:(i,s)=>i.toFixed(s),g:(i,s)=>i.toPrecision(s),o:i=>Math.round(i).toString(8),p:(i,s)=>uFe(i*100,s),r:uFe,s:zIt,X:i=>Math.round(i).toString(16).toUpperCase(),x:i=>Math.round(i).toString(16)};function hFe(i){return i}var fFe=Array.prototype.map,dFe=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function qIt(i){var s=i.grouping===void 0||i.thousands===void 0?hFe:FIt(fFe.call(i.grouping,Number),i.thousands+""),u=i.currency===void 0?"":i.currency[0]+"",d=i.currency===void 0?"":i.currency[1]+"",p=i.decimal===void 0?".":i.decimal+"",v=i.numerals===void 0?hFe:RIt(fFe.call(i.numerals,String)),b=i.percent===void 0?"%":i.percent+"",y=i.minus===void 0?"−":i.minus+"",T=i.nan===void 0?"NaN":i.nan+"";function _(P){P=tX(P);var R=P.fill,F=P.align,j=P.sign,K=P.symbol,ee=P.zero,ie=P.width,oe=P.comma,pe=P.precision,be=P.trim,ae=P.type;ae==="n"?(oe=!0,ae="g"):lFe[ae]||(pe===void 0&&(pe=12),be=!0,ae="g"),(ee||R==="0"&&F==="=")&&(ee=!0,R="0",F="=");var ne=K==="$"?u:K==="#"&&/[boxX]/.test(ae)?"0"+ae.toLowerCase():"",se=K==="$"?d:/[%p]/.test(ae)?b:"",de=lFe[ae],X=/[defgprs%]/.test(ae);pe=pe===void 0?6:/[gprs]/.test(ae)?Math.max(1,Math.min(21,pe)):Math.max(0,Math.min(20,pe));function ge(W){var xe=ne,U=se,Fe,Pe,je;if(ae==="c")U=de(W)+U,W="";else{W=+W;var Ie=W<0||1/W<0;if(W=isNaN(W)?T:de(Math.abs(W),pe),be&&(W=$It(W)),Ie&&+W==0&&j!=="+"&&(Ie=!1),xe=(Ie?j==="("?j:y:j==="-"||j==="("?"":j)+xe,U=(ae==="s"?dFe[8+cFe/3]:"")+U+(Ie&&j==="("?")":""),X){for(Fe=-1,Pe=W.length;++Feje||je>57){U=(je===46?p+W.slice(Fe+1):W.slice(Fe))+U,W=W.slice(0,Fe);break}}}oe&&!ee&&(W=s(W,1/0));var Se=xe.length+W.length+U.length,Ce=Se>1)+xe+W+U+Ce.slice(Se);break;default:W=Ce+xe+W+U;break}return v(W)}return ge.toString=function(){return P+""},ge}function A(P,R){var F=_((P=tX(P),P.type="f",P)),j=Math.max(-8,Math.min(8,Math.floor(rD(R)/3)))*3,K=Math.pow(10,-j),ee=dFe[8+j/3];return function(ie){return F(K*ie)+ee}}return{format:_,formatPrefix:A}}var nX,gFe,pFe;HIt({thousands:",",grouping:[3],currency:["$",""]});function HIt(i){return nX=qIt(i),gFe=nX.format,pFe=nX.formatPrefix,nX}function VIt(i){return Math.max(0,-rD(Math.abs(i)))}function UIt(i,s){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(rD(s)/3)))*3-rD(Math.abs(i)))}function GIt(i,s){return i=Math.abs(i),s=Math.abs(s)-i,Math.max(0,rD(s)-rD(i))+1}function rX(i,s){switch(arguments.length){case 0:break;case 1:this.range(i);break;default:this.range(s).domain(i);break}return this}const bFe=Symbol("implicit");function _F(){var i=new cBe,s=[],u=[],d=bFe;function p(v){let b=i.get(v);if(b===void 0){if(d!==bFe)return d;i.set(v,b=s.push(v)-1)}return u[b%u.length]}return p.domain=function(v){if(!arguments.length)return s.slice();s=[],i=new cBe;for(const b of v)i.has(b)||i.set(b,s.push(b)-1);return p},p.range=function(v){return arguments.length?(u=Array.from(v),p):u.slice()},p.unknown=function(v){return arguments.length?(d=v,p):d},p.copy=function(){return _F(s,u).unknown(d)},rX.apply(p,arguments),p}function qpe(){var i=_F().unknown(void 0),s=i.domain,u=i.range,d=0,p=1,v,b,y=!1,T=0,_=0,A=.5;delete i.unknown;function P(){var R=s().length,F=ps&&(u=i,i=s,s=u),function(d){return Math.max(i,Math.min(s,d))}}function XIt(i,s,u){var d=i[0],p=i[1],v=s[0],b=s[1];return p2?QIt:XIt,T=_=null,P}function P(R){return R==null||isNaN(R=+R)?v:(T||(T=y(i.map(d),s,u)))(d(b(R)))}return P.invert=function(R){return b(p((_||(_=y(s,i.map(d),L3)))(R)))},P.domain=function(R){return arguments.length?(i=Array.from(R,WIt),A()):i.slice()},P.range=function(R){return arguments.length?(s=Array.from(R),A()):s.slice()},P.rangeRound=function(R){return s=Array.from(R),u=lDt,A()},P.clamp=function(R){return arguments.length?(b=R?!0:iD,A()):b!==iD},P.interpolate=function(R){return arguments.length?(u=R,A()):u},P.unknown=function(R){return arguments.length?(v=R,P):v},function(R,F){return d=R,p=F,A()}}function wFe(){return JIt()(iD,iD)}function ZIt(i,s,u,d){var p=ppe(i,s,u),v;switch(d=tX(d??",f"),d.type){case"s":{var b=Math.max(Math.abs(i),Math.abs(s));return d.precision==null&&!isNaN(v=UIt(p,b))&&(d.precision=v),pFe(d,b)}case"":case"e":case"g":case"p":case"r":{d.precision==null&&!isNaN(v=GIt(p,Math.max(Math.abs(i),Math.abs(s))))&&(d.precision=v-(d.type==="e"));break}case"f":case"%":{d.precision==null&&!isNaN(v=VIt(p))&&(d.precision=v-(d.type==="%")*2);break}}return gFe(d)}function eOt(i){var s=i.domain;return i.ticks=function(u){var d=s();return GAt(d[0],d[d.length-1],u??10)},i.tickFormat=function(u,d){var p=s();return ZIt(p[0],p[p.length-1],u??10,d)},i.nice=function(u){u==null&&(u=10);var d=s(),p=0,v=d.length-1,b=d[p],y=d[v],T,_,A=10;for(y0;){if(_=gpe(b,y,u),_===T)return d[p]=b,d[v]=y,s(d);if(_>0)b=Math.floor(b/_)*_,y=Math.ceil(y/_)*_;else if(_<0)b=Math.ceil(b*_)/_,y=Math.floor(y*_)/_;else break;T=_}return i},i}function sD(){var i=wFe();return i.copy=function(){return vFe(i,sD())},rX.apply(i,arguments),eOt(i)}function tOt(i,s){i=i.slice();var u=0,d=i.length-1,p=i[u],v=i[d],b;return v(i(v=new Date(+v)),v),p.ceil=v=>(i(v=new Date(v-1)),s(v,1),i(v),v),p.round=v=>{const b=p(v),y=p.ceil(v);return v-b(s(v=new Date(+v),b==null?1:Math.floor(b)),v),p.range=(v,b,y)=>{const T=[];if(v=p.ceil(v),y=y==null?1:Math.floor(y),!(v0))return T;let _;do T.push(_=new Date(+v)),s(v,y),i(v);while(_h1(b=>{if(b>=b)for(;i(b),!v(b);)b.setTime(b-1)},(b,y)=>{if(b>=b)if(y<0)for(;++y<=0;)for(;s(b,-1),!v(b););else for(;--y>=0;)for(;s(b,1),!v(b););}),u&&(p.count=(v,b)=>(Vpe.setTime(+v),Upe.setTime(+b),i(Vpe),i(Upe),Math.floor(u(Vpe,Upe))),p.every=v=>(v=Math.floor(v),!isFinite(v)||!(v>0)?null:v>1?p.filter(d?b=>d(b)%v===0:b=>p.count(0,b)%v===0):p)),p}const aD=h1(()=>{},(i,s)=>{i.setTime(+i+s)},(i,s)=>s-i);aD.every=i=>(i=Math.floor(i),!isFinite(i)||!(i>0)?null:i>1?h1(s=>{s.setTime(Math.floor(s/i)*i)},(s,u)=>{s.setTime(+s+u*i)},(s,u)=>(u-s)/i):aD),aD.range;const v7=1e3,Mv=v7*60,w7=Mv*60,y7=w7*24,Gpe=y7*7,yFe=y7*30,Kpe=y7*365,b9=h1(i=>{i.setTime(i-i.getMilliseconds())},(i,s)=>{i.setTime(+i+s*v7)},(i,s)=>(s-i)/v7,i=>i.getUTCSeconds());b9.range;const AF=h1(i=>{i.setTime(i-i.getMilliseconds()-i.getSeconds()*v7)},(i,s)=>{i.setTime(+i+s*Mv)},(i,s)=>(s-i)/Mv,i=>i.getMinutes());AF.range,h1(i=>{i.setUTCSeconds(0,0)},(i,s)=>{i.setTime(+i+s*Mv)},(i,s)=>(s-i)/Mv,i=>i.getUTCMinutes()).range;const LF=h1(i=>{i.setTime(i-i.getMilliseconds()-i.getSeconds()*v7-i.getMinutes()*Mv)},(i,s)=>{i.setTime(+i+s*w7)},(i,s)=>(s-i)/w7,i=>i.getHours());LF.range,h1(i=>{i.setUTCMinutes(0,0,0)},(i,s)=>{i.setTime(+i+s*w7)},(i,s)=>(s-i)/w7,i=>i.getUTCHours()).range;const vC=h1(i=>i.setHours(0,0,0,0),(i,s)=>i.setDate(i.getDate()+s),(i,s)=>(s-i-(s.getTimezoneOffset()-i.getTimezoneOffset())*Mv)/y7,i=>i.getDate()-1);vC.range;const Wpe=h1(i=>{i.setUTCHours(0,0,0,0)},(i,s)=>{i.setUTCDate(i.getUTCDate()+s)},(i,s)=>(s-i)/y7,i=>i.getUTCDate()-1);Wpe.range,h1(i=>{i.setUTCHours(0,0,0,0)},(i,s)=>{i.setUTCDate(i.getUTCDate()+s)},(i,s)=>(s-i)/y7,i=>Math.floor(i/y7)).range;function wC(i){return h1(s=>{s.setDate(s.getDate()-(s.getDay()+7-i)%7),s.setHours(0,0,0,0)},(s,u)=>{s.setDate(s.getDate()+u*7)},(s,u)=>(u-s-(u.getTimezoneOffset()-s.getTimezoneOffset())*Mv)/Gpe)}const MF=wC(0),DF=wC(1),xFe=wC(2),kFe=wC(3),yC=wC(4),EFe=wC(5),TFe=wC(6);MF.range,DF.range,xFe.range,kFe.range,yC.range,EFe.range,TFe.range;function xC(i){return h1(s=>{s.setUTCDate(s.getUTCDate()-(s.getUTCDay()+7-i)%7),s.setUTCHours(0,0,0,0)},(s,u)=>{s.setUTCDate(s.getUTCDate()+u*7)},(s,u)=>(u-s)/Gpe)}const CFe=xC(0),iX=xC(1),nOt=xC(2),rOt=xC(3),oD=xC(4),iOt=xC(5),sOt=xC(6);CFe.range,iX.range,nOt.range,rOt.range,oD.range,iOt.range,sOt.range;const IF=h1(i=>{i.setDate(1),i.setHours(0,0,0,0)},(i,s)=>{i.setMonth(i.getMonth()+s)},(i,s)=>s.getMonth()-i.getMonth()+(s.getFullYear()-i.getFullYear())*12,i=>i.getMonth());IF.range,h1(i=>{i.setUTCDate(1),i.setUTCHours(0,0,0,0)},(i,s)=>{i.setUTCMonth(i.getUTCMonth()+s)},(i,s)=>s.getUTCMonth()-i.getUTCMonth()+(s.getUTCFullYear()-i.getUTCFullYear())*12,i=>i.getUTCMonth()).range;const x7=h1(i=>{i.setMonth(0,1),i.setHours(0,0,0,0)},(i,s)=>{i.setFullYear(i.getFullYear()+s)},(i,s)=>s.getFullYear()-i.getFullYear(),i=>i.getFullYear());x7.every=i=>!isFinite(i=Math.floor(i))||!(i>0)?null:h1(s=>{s.setFullYear(Math.floor(s.getFullYear()/i)*i),s.setMonth(0,1),s.setHours(0,0,0,0)},(s,u)=>{s.setFullYear(s.getFullYear()+u*i)}),x7.range;const kC=h1(i=>{i.setUTCMonth(0,1),i.setUTCHours(0,0,0,0)},(i,s)=>{i.setUTCFullYear(i.getUTCFullYear()+s)},(i,s)=>s.getUTCFullYear()-i.getUTCFullYear(),i=>i.getUTCFullYear());kC.every=i=>!isFinite(i=Math.floor(i))||!(i>0)?null:h1(s=>{s.setUTCFullYear(Math.floor(s.getUTCFullYear()/i)*i),s.setUTCMonth(0,1),s.setUTCHours(0,0,0,0)},(s,u)=>{s.setUTCFullYear(s.getUTCFullYear()+u*i)}),kC.range;function aOt(i,s,u,d,p,v){const b=[[b9,1,v7],[b9,5,5*v7],[b9,15,15*v7],[b9,30,30*v7],[v,1,Mv],[v,5,5*Mv],[v,15,15*Mv],[v,30,30*Mv],[p,1,w7],[p,3,3*w7],[p,6,6*w7],[p,12,12*w7],[d,1,y7],[d,2,2*y7],[u,1,Gpe],[s,1,yFe],[s,3,3*yFe],[i,1,Kpe]];function y(_,A,P){const R=A<_;R&&([_,A]=[A,_]);const F=P&&typeof P.range=="function"?P:T(_,A,P),j=F?F.range(_,+A+1):[];return R?j.reverse():j}function T(_,A,P){const R=Math.abs(A-_)/P,F=dpe(([,,ee])=>ee).right(b,R);if(F===b.length)return i.every(ppe(_/Kpe,A/Kpe,P));if(F===0)return aD.every(Math.max(ppe(_,A,P),1));const[j,K]=b[R/b[F-1][2]53)return null;"w"in Dt||(Dt.w=1),"Z"in Dt?(On=Xpe(OF(Dt.y,0,1)),ht=On.getUTCDay(),On=ht>4||ht===0?iX.ceil(On):iX(On),On=Wpe.offset(On,(Dt.V-1)*7),Dt.y=On.getUTCFullYear(),Dt.m=On.getUTCMonth(),Dt.d=On.getUTCDate()+(Dt.w+6)%7):(On=Ype(OF(Dt.y,0,1)),ht=On.getDay(),On=ht>4||ht===0?DF.ceil(On):DF(On),On=vC.offset(On,(Dt.V-1)*7),Dt.y=On.getFullYear(),Dt.m=On.getMonth(),Dt.d=On.getDate()+(Dt.w+6)%7)}else("W"in Dt||"U"in Dt)&&("w"in Dt||(Dt.w="u"in Dt?Dt.u%7:"W"in Dt?1:0),ht="Z"in Dt?Xpe(OF(Dt.y,0,1)).getUTCDay():Ype(OF(Dt.y,0,1)).getDay(),Dt.m=0,Dt.d="W"in Dt?(Dt.w+6)%7+Dt.W*7-(ht+5)%7:Dt.w+Dt.U*7-(ht+6)%7);return"Z"in Dt?(Dt.H+=Dt.Z/100|0,Dt.M+=Dt.Z%100,Xpe(Dt)):Ype(Dt)}}function de(xt,Pt,Qe,Dt){for(var kt=0,On=Pt.length,ht=Qe.length,zr,yt;kt=ht)return-1;if(zr=Pt.charCodeAt(kt++),zr===37){if(zr=Pt.charAt(kt++),yt=ae[zr in SFe?Pt.charAt(kt++):zr],!yt||(Dt=yt(xt,Qe,Dt))<0)return-1}else if(zr!=Qe.charCodeAt(Dt++))return-1}return Dt}function X(xt,Pt,Qe){var Dt=_.exec(Pt.slice(Qe));return Dt?(xt.p=A.get(Dt[0].toLowerCase()),Qe+Dt[0].length):-1}function ge(xt,Pt,Qe){var Dt=F.exec(Pt.slice(Qe));return Dt?(xt.w=j.get(Dt[0].toLowerCase()),Qe+Dt[0].length):-1}function W(xt,Pt,Qe){var Dt=P.exec(Pt.slice(Qe));return Dt?(xt.w=R.get(Dt[0].toLowerCase()),Qe+Dt[0].length):-1}function xe(xt,Pt,Qe){var Dt=ie.exec(Pt.slice(Qe));return Dt?(xt.m=oe.get(Dt[0].toLowerCase()),Qe+Dt[0].length):-1}function U(xt,Pt,Qe){var Dt=K.exec(Pt.slice(Qe));return Dt?(xt.m=ee.get(Dt[0].toLowerCase()),Qe+Dt[0].length):-1}function Fe(xt,Pt,Qe){return de(xt,s,Pt,Qe)}function Pe(xt,Pt,Qe){return de(xt,u,Pt,Qe)}function je(xt,Pt,Qe){return de(xt,d,Pt,Qe)}function Ie(xt){return b[xt.getDay()]}function Se(xt){return v[xt.getDay()]}function Ce(xt){return T[xt.getMonth()]}function ke(xt){return y[xt.getMonth()]}function Ke(xt){return p[+(xt.getHours()>=12)]}function Ft(xt){return 1+~~(xt.getMonth()/3)}function Ne(xt){return b[xt.getUTCDay()]}function gn(xt){return v[xt.getUTCDay()]}function _t(xt){return T[xt.getUTCMonth()]}function Et(xt){return y[xt.getUTCMonth()]}function Gt(xt){return p[+(xt.getUTCHours()>=12)]}function ln(xt){return 1+~~(xt.getUTCMonth()/3)}return{format:function(xt){var Pt=ne(xt+="",pe);return Pt.toString=function(){return xt},Pt},parse:function(xt){var Pt=se(xt+="",!1);return Pt.toString=function(){return xt},Pt},utcFormat:function(xt){var Pt=ne(xt+="",be);return Pt.toString=function(){return xt},Pt},utcParse:function(xt){var Pt=se(xt+="",!0);return Pt.toString=function(){return xt},Pt}}}var SFe={"-":"",_:" ",0:"0"},rd=/^\s*\d+/,lOt=/^%/,hOt=/[\\^$*+?|[\]().{}]/g;function mu(i,s,u){var d=i<0?"-":"",p=(d?-i:i)+"",v=p.length;return d+(v[s.toLowerCase(),u]))}function dOt(i,s,u){var d=rd.exec(s.slice(u,u+1));return d?(i.w=+d[0],u+d[0].length):-1}function gOt(i,s,u){var d=rd.exec(s.slice(u,u+1));return d?(i.u=+d[0],u+d[0].length):-1}function pOt(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.U=+d[0],u+d[0].length):-1}function bOt(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.V=+d[0],u+d[0].length):-1}function mOt(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.W=+d[0],u+d[0].length):-1}function _Fe(i,s,u){var d=rd.exec(s.slice(u,u+4));return d?(i.y=+d[0],u+d[0].length):-1}function AFe(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.y=+d[0]+(+d[0]>68?1900:2e3),u+d[0].length):-1}function vOt(i,s,u){var d=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(s.slice(u,u+6));return d?(i.Z=d[1]?0:-(d[2]+(d[3]||"00")),u+d[0].length):-1}function wOt(i,s,u){var d=rd.exec(s.slice(u,u+1));return d?(i.q=d[0]*3-3,u+d[0].length):-1}function yOt(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.m=d[0]-1,u+d[0].length):-1}function LFe(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.d=+d[0],u+d[0].length):-1}function xOt(i,s,u){var d=rd.exec(s.slice(u,u+3));return d?(i.m=0,i.d=+d[0],u+d[0].length):-1}function MFe(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.H=+d[0],u+d[0].length):-1}function kOt(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.M=+d[0],u+d[0].length):-1}function EOt(i,s,u){var d=rd.exec(s.slice(u,u+2));return d?(i.S=+d[0],u+d[0].length):-1}function TOt(i,s,u){var d=rd.exec(s.slice(u,u+3));return d?(i.L=+d[0],u+d[0].length):-1}function COt(i,s,u){var d=rd.exec(s.slice(u,u+6));return d?(i.L=Math.floor(d[0]/1e3),u+d[0].length):-1}function SOt(i,s,u){var d=lOt.exec(s.slice(u,u+1));return d?u+d[0].length:-1}function _Ot(i,s,u){var d=rd.exec(s.slice(u));return d?(i.Q=+d[0],u+d[0].length):-1}function AOt(i,s,u){var d=rd.exec(s.slice(u));return d?(i.s=+d[0],u+d[0].length):-1}function DFe(i,s){return mu(i.getDate(),s,2)}function LOt(i,s){return mu(i.getHours(),s,2)}function MOt(i,s){return mu(i.getHours()%12||12,s,2)}function DOt(i,s){return mu(1+vC.count(x7(i),i),s,3)}function IFe(i,s){return mu(i.getMilliseconds(),s,3)}function IOt(i,s){return IFe(i,s)+"000"}function OOt(i,s){return mu(i.getMonth()+1,s,2)}function NOt(i,s){return mu(i.getMinutes(),s,2)}function POt(i,s){return mu(i.getSeconds(),s,2)}function BOt(i){var s=i.getDay();return s===0?7:s}function FOt(i,s){return mu(MF.count(x7(i)-1,i),s,2)}function OFe(i){var s=i.getDay();return s>=4||s===0?yC(i):yC.ceil(i)}function ROt(i,s){return i=OFe(i),mu(yC.count(x7(i),i)+(x7(i).getDay()===4),s,2)}function jOt(i){return i.getDay()}function $Ot(i,s){return mu(DF.count(x7(i)-1,i),s,2)}function zOt(i,s){return mu(i.getFullYear()%100,s,2)}function qOt(i,s){return i=OFe(i),mu(i.getFullYear()%100,s,2)}function HOt(i,s){return mu(i.getFullYear()%1e4,s,4)}function VOt(i,s){var u=i.getDay();return i=u>=4||u===0?yC(i):yC.ceil(i),mu(i.getFullYear()%1e4,s,4)}function UOt(i){var s=i.getTimezoneOffset();return(s>0?"-":(s*=-1,"+"))+mu(s/60|0,"0",2)+mu(s%60,"0",2)}function NFe(i,s){return mu(i.getUTCDate(),s,2)}function GOt(i,s){return mu(i.getUTCHours(),s,2)}function KOt(i,s){return mu(i.getUTCHours()%12||12,s,2)}function WOt(i,s){return mu(1+Wpe.count(kC(i),i),s,3)}function PFe(i,s){return mu(i.getUTCMilliseconds(),s,3)}function YOt(i,s){return PFe(i,s)+"000"}function XOt(i,s){return mu(i.getUTCMonth()+1,s,2)}function QOt(i,s){return mu(i.getUTCMinutes(),s,2)}function JOt(i,s){return mu(i.getUTCSeconds(),s,2)}function ZOt(i){var s=i.getUTCDay();return s===0?7:s}function eNt(i,s){return mu(CFe.count(kC(i)-1,i),s,2)}function BFe(i){var s=i.getUTCDay();return s>=4||s===0?oD(i):oD.ceil(i)}function tNt(i,s){return i=BFe(i),mu(oD.count(kC(i),i)+(kC(i).getUTCDay()===4),s,2)}function nNt(i){return i.getUTCDay()}function rNt(i,s){return mu(iX.count(kC(i)-1,i),s,2)}function iNt(i,s){return mu(i.getUTCFullYear()%100,s,2)}function sNt(i,s){return i=BFe(i),mu(i.getUTCFullYear()%100,s,2)}function aNt(i,s){return mu(i.getUTCFullYear()%1e4,s,4)}function oNt(i,s){var u=i.getUTCDay();return i=u>=4||u===0?oD(i):oD.ceil(i),mu(i.getUTCFullYear()%1e4,s,4)}function cNt(){return"+0000"}function FFe(){return"%"}function RFe(i){return+i}function jFe(i){return Math.floor(+i/1e3)}var cD,sX;uNt({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"]});function uNt(i){return cD=uOt(i),sX=cD.format,cD.parse,cD.utcFormat,cD.utcParse,cD}function lNt(i){return new Date(i)}function hNt(i){return i instanceof Date?+i:+new Date(+i)}function $Fe(i,s,u,d,p,v,b,y,T,_){var A=wFe(),P=A.invert,R=A.domain,F=_(".%L"),j=_(":%S"),K=_("%I:%M"),ee=_("%I %p"),ie=_("%a %d"),oe=_("%b %d"),pe=_("%B"),be=_("%Y");function ae(ne){return(T(ne)1?0:i<-1?BF:Math.acos(i)}function HFe(i){return i>=1?aX:i<=-1?-aX:Math.asin(i)}function VFe(i){let s=3;return i.digits=function(u){if(!arguments.length)return s;if(u==null)s=null;else{const d=Math.floor(u);if(!(d>=0))throw new RangeError(`invalid digits: ${u}`);s=d}return i},()=>new DIt(s)}function bNt(i){return i.innerRadius}function mNt(i){return i.outerRadius}function vNt(i){return i.startAngle}function wNt(i){return i.endAngle}function yNt(i){return i&&i.padAngle}function xNt(i,s,u,d,p,v,b,y){var T=u-i,_=d-s,A=b-p,P=y-v,R=P*T-A*_;if(!(R*RFe*Fe+Pe*Pe&&(de=ge,X=W),{cx:de,cy:X,x01:-A,y01:-P,x11:de*(p/ae-1),y11:X*(p/ae-1)}}function lD(){var i=bNt,s=mNt,u=Wf(0),d=null,p=vNt,v=wNt,b=yNt,y=null,T=VFe(_);function _(){var A,P,R=+i.apply(this,arguments),F=+s.apply(this,arguments),j=p.apply(this,arguments)-aX,K=v.apply(this,arguments)-aX,ee=qFe(K-j),ie=K>j;if(y||(y=A=T()),FIg))y.moveTo(0,0);else if(ee>oX-Ig)y.moveTo(F*EC(j),F*z4(j)),y.arc(0,0,F,j,K,!ie),R>Ig&&(y.moveTo(R*EC(K),R*z4(K)),y.arc(0,0,R,K,j,ie));else{var oe=j,pe=K,be=j,ae=K,ne=ee,se=ee,de=b.apply(this,arguments)/2,X=de>Ig&&(d?+d.apply(this,arguments):uD(R*R+F*F)),ge=Qpe(qFe(F-R)/2,+u.apply(this,arguments)),W=ge,xe=ge,U,Fe;if(X>Ig){var Pe=HFe(X/R*z4(de)),je=HFe(X/F*z4(de));(ne-=Pe*2)>Ig?(Pe*=ie?1:-1,be+=Pe,ae-=Pe):(ne=0,be=ae=(j+K)/2),(se-=je*2)>Ig?(je*=ie?1:-1,oe+=je,pe-=je):(se=0,oe=pe=(j+K)/2)}var Ie=F*EC(oe),Se=F*z4(oe),Ce=R*EC(ae),ke=R*z4(ae);if(ge>Ig){var Ke=F*EC(pe),Ft=F*z4(pe),Ne=R*EC(be),gn=R*z4(be),_t;if(eeIg?xe>Ig?(U=cX(Ne,gn,Ie,Se,F,xe,ie),Fe=cX(Ke,Ft,Ce,ke,F,xe,ie),y.moveTo(U.cx+U.x01,U.cy+U.y01),xeIg)||!(ne>Ig)?y.lineTo(Ce,ke):W>Ig?(U=cX(Ce,ke,Ke,Ft,R,-W,ie),Fe=cX(Ie,Se,Ne,gn,R,-W,ie),y.lineTo(U.cx+U.x01,U.cy+U.y01),Wi?1:s>=i?0:NaN}function CNt(i){return i}function SNt(){var i=CNt,s=TNt,u=null,d=Wf(0),p=Wf(oX),v=Wf(0);function b(y){var T,_=(y=UFe(y)).length,A,P,R=0,F=new Array(_),j=new Array(_),K=+d.apply(this,arguments),ee=Math.min(oX,Math.max(-oX,p.apply(this,arguments)-K)),ie,oe=Math.min(Math.abs(ee)/_,v.apply(this,arguments)),pe=oe*(ee<0?-1:1),be;for(T=0;T<_;++T)(be=j[F[T]=T]=+i(y[T],T,y))>0&&(R+=be);for(s!=null?F.sort(function(ae,ne){return s(j[ae],j[ne])}):u!=null&&F.sort(function(ae,ne){return u(y[ae],y[ne])}),T=0,P=R?(ee-_*pe)/R:0;T<_;++T,K=ie)A=F[T],be=j[A],ie=K+(be>0?be*P:0)+pe,j[A]={data:y[A],index:T,value:be,startAngle:K,endAngle:ie,padAngle:oe};return j}return b.value=function(y){return arguments.length?(i=typeof y=="function"?y:Wf(+y),b):i},b.sortValues=function(y){return arguments.length?(s=y,u=null,b):s},b.sort=function(y){return arguments.length?(u=y,s=null,b):u},b.startAngle=function(y){return arguments.length?(d=typeof y=="function"?y:Wf(+y),b):d},b.endAngle=function(y){return arguments.length?(p=typeof y=="function"?y:Wf(+y),b):p},b.padAngle=function(y){return arguments.length?(v=typeof y=="function"?y:Wf(+y),b):v},b}class KFe{constructor(s,u){this._context=s,this._x=u}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(s,u){switch(s=+s,u=+u,this._point){case 0:{this._point=1,this._line?this._context.lineTo(s,u):this._context.moveTo(s,u);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+s)/2,this._y0,this._x0,u,s,u):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+u)/2,s,this._y0,s,u);break}}this._x0=s,this._y0=u}}function _Nt(i){return new KFe(i,!0)}function ANt(i){return new KFe(i,!1)}function m9(){}function uX(i,s,u){i._context.bezierCurveTo((2*i._x0+i._x1)/3,(2*i._y0+i._y1)/3,(i._x0+2*i._x1)/3,(i._y0+2*i._y1)/3,(i._x0+4*i._x1+s)/6,(i._y0+4*i._y1+u)/6)}function lX(i){this._context=i}lX.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:uX(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},point:function(i,s){switch(i=+i,s=+s,this._point){case 0:this._point=1,this._line?this._context.lineTo(i,s):this._context.moveTo(i,s);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:uX(this,i,s);break}this._x0=this._x1,this._x1=i,this._y0=this._y1,this._y1=s}};function FF(i){return new lX(i)}function WFe(i){this._context=i}WFe.prototype={areaStart:m9,areaEnd:m9,lineStart: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},lineEnd: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}}},point:function(i,s){switch(i=+i,s=+s,this._point){case 0:this._point=1,this._x2=i,this._y2=s;break;case 1:this._point=2,this._x3=i,this._y3=s;break;case 2:this._point=3,this._x4=i,this._y4=s,this._context.moveTo((this._x0+4*this._x1+i)/6,(this._y0+4*this._y1+s)/6);break;default:uX(this,i,s);break}this._x0=this._x1,this._x1=i,this._y0=this._y1,this._y1=s}};function LNt(i){return new WFe(i)}function YFe(i){this._context=i}YFe.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(i,s){switch(i=+i,s=+s,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var u=(this._x0+4*this._x1+i)/6,d=(this._y0+4*this._y1+s)/6;this._line?this._context.lineTo(u,d):this._context.moveTo(u,d);break;case 3:this._point=4;default:uX(this,i,s);break}this._x0=this._x1,this._x1=i,this._y0=this._y1,this._y1=s}};function MNt(i){return new YFe(i)}function XFe(i,s){this._basis=new lX(i),this._beta=s}XFe.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var i=this._x,s=this._y,u=i.length-1;if(u>0)for(var d=i[0],p=s[0],v=i[u]-d,b=s[u]-p,y=-1,T;++y<=u;)T=y/u,this._basis.point(this._beta*i[y]+(1-this._beta)*(d+T*v),this._beta*s[y]+(1-this._beta)*(p+T*b));this._x=this._y=null,this._basis.lineEnd()},point:function(i,s){this._x.push(+i),this._y.push(+s)}};const DNt=function i(s){function u(d){return s===1?new lX(d):new XFe(d,s)}return u.beta=function(d){return i(+d)},u}(.85);function hX(i,s,u){i._context.bezierCurveTo(i._x1+i._k*(i._x2-i._x0),i._y1+i._k*(i._y2-i._y0),i._x2+i._k*(i._x1-s),i._y2+i._k*(i._y1-u),i._x2,i._y2)}function Jpe(i,s){this._context=i,this._k=(1-s)/6}Jpe.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:hX(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(i,s){switch(i=+i,s=+s,this._point){case 0:this._point=1,this._line?this._context.lineTo(i,s):this._context.moveTo(i,s);break;case 1:this._point=2,this._x1=i,this._y1=s;break;case 2:this._point=3;default:hX(this,i,s);break}this._x0=this._x1,this._x1=this._x2,this._x2=i,this._y0=this._y1,this._y1=this._y2,this._y2=s}};const INt=function i(s){function u(d){return new Jpe(d,s)}return u.tension=function(d){return i(+d)},u}(0);function Zpe(i,s){this._context=i,this._k=(1-s)/6}Zpe.prototype={areaStart:m9,areaEnd:m9,lineStart: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},lineEnd: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}}},point:function(i,s){switch(i=+i,s=+s,this._point){case 0:this._point=1,this._x3=i,this._y3=s;break;case 1:this._point=2,this._context.moveTo(this._x4=i,this._y4=s);break;case 2:this._point=3,this._x5=i,this._y5=s;break;default:hX(this,i,s);break}this._x0=this._x1,this._x1=this._x2,this._x2=i,this._y0=this._y1,this._y1=this._y2,this._y2=s}};const ONt=function i(s){function u(d){return new Zpe(d,s)}return u.tension=function(d){return i(+d)},u}(0);function e2e(i,s){this._context=i,this._k=(1-s)/6}e2e.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(i,s){switch(i=+i,s=+s,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:hX(this,i,s);break}this._x0=this._x1,this._x1=this._x2,this._x2=i,this._y0=this._y1,this._y1=this._y2,this._y2=s}};const NNt=function i(s){function u(d){return new e2e(d,s)}return u.tension=function(d){return i(+d)},u}(0);function t2e(i,s,u){var d=i._x1,p=i._y1,v=i._x2,b=i._y2;if(i._l01_a>Ig){var y=2*i._l01_2a+3*i._l01_a*i._l12_a+i._l12_2a,T=3*i._l01_a*(i._l01_a+i._l12_a);d=(d*y-i._x0*i._l12_2a+i._x2*i._l01_2a)/T,p=(p*y-i._y0*i._l12_2a+i._y2*i._l01_2a)/T}if(i._l23_a>Ig){var _=2*i._l23_2a+3*i._l23_a*i._l12_a+i._l12_2a,A=3*i._l23_a*(i._l23_a+i._l12_a);v=(v*_+i._x1*i._l23_2a-s*i._l12_2a)/A,b=(b*_+i._y1*i._l23_2a-u*i._l12_2a)/A}i._context.bezierCurveTo(d,p,v,b,i._x2,i._y2)}function QFe(i,s){this._context=i,this._alpha=s}QFe.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart: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},lineEnd: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},point:function(i,s){if(i=+i,s=+s,this._point){var u=this._x2-i,d=this._y2-s;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(u*u+d*d,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(i,s):this._context.moveTo(i,s);break;case 1:this._point=2;break;case 2:this._point=3;default:t2e(this,i,s);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=i,this._y0=this._y1,this._y1=this._y2,this._y2=s}};const PNt=function i(s){function u(d){return s?new QFe(d,s):new Jpe(d,0)}return u.alpha=function(d){return i(+d)},u}(.5);function JFe(i,s){this._context=i,this._alpha=s}JFe.prototype={areaStart:m9,areaEnd:m9,lineStart: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},lineEnd: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}}},point:function(i,s){if(i=+i,s=+s,this._point){var u=this._x2-i,d=this._y2-s;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(u*u+d*d,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=i,this._y3=s;break;case 1:this._point=2,this._context.moveTo(this._x4=i,this._y4=s);break;case 2:this._point=3,this._x5=i,this._y5=s;break;default:t2e(this,i,s);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=i,this._y0=this._y1,this._y1=this._y2,this._y2=s}};const BNt=function i(s){function u(d){return s?new JFe(d,s):new Zpe(d,0)}return u.alpha=function(d){return i(+d)},u}(.5);function ZFe(i,s){this._context=i,this._alpha=s}ZFe.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart: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},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(i,s){if(i=+i,s=+s,this._point){var u=this._x2-i,d=this._y2-s;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(u*u+d*d,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:t2e(this,i,s);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=i,this._y0=this._y1,this._y1=this._y2,this._y2=s}};const FNt=function i(s){function u(d){return s?new ZFe(d,s):new e2e(d,0)}return u.alpha=function(d){return i(+d)},u}(.5);function eRe(i){this._context=i}eRe.prototype={areaStart:m9,areaEnd:m9,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(i,s){i=+i,s=+s,this._point?this._context.lineTo(i,s):(this._point=1,this._context.moveTo(i,s))}};function RNt(i){return new eRe(i)}function tRe(i){return i<0?-1:1}function nRe(i,s,u){var d=i._x1-i._x0,p=s-i._x1,v=(i._y1-i._y0)/(d||p<0&&-0),b=(u-i._y1)/(p||d<0&&-0),y=(v*p+b*d)/(d+p);return(tRe(v)+tRe(b))*Math.min(Math.abs(v),Math.abs(b),.5*Math.abs(y))||0}function rRe(i,s){var u=i._x1-i._x0;return u?(3*(i._y1-i._y0)/u-s)/2:s}function n2e(i,s,u){var d=i._x0,p=i._y0,v=i._x1,b=i._y1,y=(v-d)/3;i._context.bezierCurveTo(d+y,p+y*s,v-y,b-y*u,v,b)}function fX(i){this._context=i}fX.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:n2e(this,this._t0,rRe(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(i,s){var u=NaN;if(i=+i,s=+s,!(i===this._x1&&s===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(i,s):this._context.moveTo(i,s);break;case 1:this._point=2;break;case 2:this._point=3,n2e(this,rRe(this,u=nRe(this,i,s)),u);break;default:n2e(this,this._t0,u=nRe(this,i,s));break}this._x0=this._x1,this._x1=i,this._y0=this._y1,this._y1=s,this._t0=u}}};function iRe(i){this._context=new sRe(i)}(iRe.prototype=Object.create(fX.prototype)).point=function(i,s){fX.prototype.point.call(this,s,i)};function sRe(i){this._context=i}sRe.prototype={moveTo:function(i,s){this._context.moveTo(s,i)},closePath:function(){this._context.closePath()},lineTo:function(i,s){this._context.lineTo(s,i)},bezierCurveTo:function(i,s,u,d,p,v){this._context.bezierCurveTo(s,i,d,u,v,p)}};function jNt(i){return new fX(i)}function $Nt(i){return new iRe(i)}function aRe(i){this._context=i}aRe.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var i=this._x,s=this._y,u=i.length;if(u)if(this._line?this._context.lineTo(i[0],s[0]):this._context.moveTo(i[0],s[0]),u===2)this._context.lineTo(i[1],s[1]);else for(var d=oRe(i),p=oRe(s),v=0,b=1;b=0;--s)p[s]=(b[s]-p[s+1])/v[s];for(v[u-1]=(i[u]+p[u-1])/2,s=0;s=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(i,s){switch(i=+i,s=+s,this._point){case 0:this._point=1,this._line?this._context.lineTo(i,s):this._context.moveTo(i,s);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,s),this._context.lineTo(i,s);else{var u=this._x*(1-this._t)+i*this._t;this._context.lineTo(u,this._y),this._context.lineTo(u,s)}break}}this._x=i,this._y=s}};function qNt(i){return new dX(i,.5)}function HNt(i){return new dX(i,0)}function VNt(i){return new dX(i,1)}function RF(i,s,u){this.k=i,this.x=s,this.y=u}RF.prototype={constructor:RF,scale:function(i){return i===1?this:new RF(this.k*i,this.x,this.y)},translate:function(i,s){return i===0&s===0?this:new RF(this.k,this.x+this.k*i,this.y+this.k*s)},apply:function(i){return[i[0]*this.k+this.x,i[1]*this.k+this.y]},applyX:function(i){return i*this.k+this.x},applyY:function(i){return i*this.k+this.y},invert:function(i){return[(i[0]-this.x)/this.k,(i[1]-this.y)/this.k]},invertX:function(i){return(i-this.x)/this.k},invertY:function(i){return(i-this.y)/this.k},rescaleX:function(i){return i.copy().domain(i.range().map(this.invertX,this).map(i.invert,i))},rescaleY:function(i){return i.copy().domain(i.range().map(this.invertY,this).map(i.invert,i))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},RF.prototype;/*! @license DOMPurify 3.0.9 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.9/LICENSE */const{entries:cRe,setPrototypeOf:uRe,isFrozen:UNt,getPrototypeOf:GNt,getOwnPropertyDescriptor:KNt}=Object;let{freeze:Ep,seal:D3,create:lRe}=Object,{apply:r2e,construct:i2e}=typeof Reflect<"u"&&Reflect;Ep||(Ep=function(s){return s}),D3||(D3=function(s){return s}),r2e||(r2e=function(s,u,d){return s.apply(u,d)}),i2e||(i2e=function(s,u){return new s(...u)});const gX=sm(Array.prototype.forEach),hRe=sm(Array.prototype.pop),jF=sm(Array.prototype.push),pX=sm(String.prototype.toLowerCase),s2e=sm(String.prototype.toString),WNt=sm(String.prototype.match),$F=sm(String.prototype.replace),YNt=sm(String.prototype.indexOf),XNt=sm(String.prototype.trim),I3=sm(Object.prototype.hasOwnProperty),im=sm(RegExp.prototype.test),zF=QNt(TypeError);function sm(i){return function(s){for(var u=arguments.length,d=new Array(u>1?u-1:0),p=1;p2&&arguments[2]!==void 0?arguments[2]:pX;uRe&&uRe(i,null);let d=s.length;for(;d--;){let p=s[d];if(typeof p=="string"){const v=u(p);v!==p&&(UNt(s)||(s[d]=v),p=v)}i[p]=!0}return i}function JNt(i){for(let s=0;s/gm),rPt=D3(/\${[\w\W]*}/gm),iPt=D3(/^data-[\-\w.\u00B7-\uFFFF]/),sPt=D3(/^aria-[\-\w]+$/),bRe=D3(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),aPt=D3(/^(?:\w+script|data):/i),oPt=D3(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),mRe=D3(/^html$/i);var vRe=Object.freeze({__proto__:null,MUSTACHE_EXPR:tPt,ERB_EXPR:nPt,TMPLIT_EXPR:rPt,DATA_ATTR:iPt,ARIA_ATTR:sPt,IS_ALLOWED_URI:bRe,IS_SCRIPT_OR_DATA:aPt,ATTR_WHITESPACE:oPt,DOCTYPE_NAME:mRe});const cPt=function(){return typeof window>"u"?null:window},uPt=function(s,u){if(typeof s!="object"||typeof s.createPolicy!="function")return null;let d=null;const p="data-tt-policy-suffix";u&&u.hasAttribute(p)&&(d=u.getAttribute(p));const v="dompurify"+(d?"#"+d:"");try{return s.createPolicy(v,{createHTML(b){return b},createScriptURL(b){return b}})}catch{return console.warn("TrustedTypes policy "+v+" could not be created."),null}};function wRe(){let i=arguments.length>0&&arguments[0]!==void 0?arguments[0]:cPt();const s=as=>wRe(as);if(s.version="3.0.9",s.removed=[],!i||!i.document||i.document.nodeType!==9)return s.isSupported=!1,s;let{document:u}=i;const d=u,p=d.currentScript,{DocumentFragment:v,HTMLTemplateElement:b,Node:y,Element:T,NodeFilter:_,NamedNodeMap:A=i.NamedNodeMap||i.MozNamedAttrMap,HTMLFormElement:P,DOMParser:R,trustedTypes:F}=i,j=T.prototype,K=bX(j,"cloneNode"),ee=bX(j,"nextSibling"),ie=bX(j,"childNodes"),oe=bX(j,"parentNode");if(typeof b=="function"){const as=u.createElement("template");as.content&&as.content.ownerDocument&&(u=as.content.ownerDocument)}let pe,be="";const{implementation:ae,createNodeIterator:ne,createDocumentFragment:se,getElementsByTagName:de}=u,{importNode:X}=d;let ge={};s.isSupported=typeof cRe=="function"&&typeof oe=="function"&&ae&&ae.createHTMLDocument!==void 0;const{MUSTACHE_EXPR:W,ERB_EXPR:xe,TMPLIT_EXPR:U,DATA_ATTR:Fe,ARIA_ATTR:Pe,IS_SCRIPT_OR_DATA:je,ATTR_WHITESPACE:Ie}=vRe;let{IS_ALLOWED_URI:Se}=vRe,Ce=null;const ke=Cc({},[...fRe,...a2e,...o2e,...c2e,...dRe]);let Ke=null;const Ft=Cc({},[...gRe,...u2e,...pRe,...mX]);let Ne=Object.seal(lRe(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}})),gn=null,_t=null,Et=!0,Gt=!0,ln=!1,xt=!0,Pt=!1,Qe=!1,Dt=!1,kt=!1,On=!1,ht=!1,zr=!1,yt=!0,ji=!1;const xi="user-content-";let Ma=!0,zs=!1,ao={},Tr=null;const Fn=Cc({},["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"]);let qn=null;const Un=Cc({},["audio","video","img","source","image","track"]);let At=null;const wt=Cc({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),on="http://www.w3.org/1998/Math/MathML",fn="http://www.w3.org/2000/svg",An="http://www.w3.org/1999/xhtml";let oo=An,jo=!1,$o=null;const Pa=Cc({},[on,fn,An],s2e);let wo=null;const _s=["application/xhtml+xml","text/html"],tl="text/html";let da=null,j0=null;const pm=u.createElement("form"),Ml=function(wn){return wn instanceof RegExp||wn instanceof Function},Xc=function(){let wn=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(j0&&j0===wn)){if((!wn||typeof wn!="object")&&(wn={}),wn=TC(wn),wo=_s.indexOf(wn.PARSER_MEDIA_TYPE)===-1?tl:wn.PARSER_MEDIA_TYPE,da=wo==="application/xhtml+xml"?s2e:pX,Ce=I3(wn,"ALLOWED_TAGS")?Cc({},wn.ALLOWED_TAGS,da):ke,Ke=I3(wn,"ALLOWED_ATTR")?Cc({},wn.ALLOWED_ATTR,da):Ft,$o=I3(wn,"ALLOWED_NAMESPACES")?Cc({},wn.ALLOWED_NAMESPACES,s2e):Pa,At=I3(wn,"ADD_URI_SAFE_ATTR")?Cc(TC(wt),wn.ADD_URI_SAFE_ATTR,da):wt,qn=I3(wn,"ADD_DATA_URI_TAGS")?Cc(TC(Un),wn.ADD_DATA_URI_TAGS,da):Un,Tr=I3(wn,"FORBID_CONTENTS")?Cc({},wn.FORBID_CONTENTS,da):Fn,gn=I3(wn,"FORBID_TAGS")?Cc({},wn.FORBID_TAGS,da):{},_t=I3(wn,"FORBID_ATTR")?Cc({},wn.FORBID_ATTR,da):{},ao=I3(wn,"USE_PROFILES")?wn.USE_PROFILES:!1,Et=wn.ALLOW_ARIA_ATTR!==!1,Gt=wn.ALLOW_DATA_ATTR!==!1,ln=wn.ALLOW_UNKNOWN_PROTOCOLS||!1,xt=wn.ALLOW_SELF_CLOSE_IN_ATTR!==!1,Pt=wn.SAFE_FOR_TEMPLATES||!1,Qe=wn.WHOLE_DOCUMENT||!1,On=wn.RETURN_DOM||!1,ht=wn.RETURN_DOM_FRAGMENT||!1,zr=wn.RETURN_TRUSTED_TYPE||!1,kt=wn.FORCE_BODY||!1,yt=wn.SANITIZE_DOM!==!1,ji=wn.SANITIZE_NAMED_PROPS||!1,Ma=wn.KEEP_CONTENT!==!1,zs=wn.IN_PLACE||!1,Se=wn.ALLOWED_URI_REGEXP||bRe,oo=wn.NAMESPACE||An,Ne=wn.CUSTOM_ELEMENT_HANDLING||{},wn.CUSTOM_ELEMENT_HANDLING&&Ml(wn.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Ne.tagNameCheck=wn.CUSTOM_ELEMENT_HANDLING.tagNameCheck),wn.CUSTOM_ELEMENT_HANDLING&&Ml(wn.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Ne.attributeNameCheck=wn.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),wn.CUSTOM_ELEMENT_HANDLING&&typeof wn.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(Ne.allowCustomizedBuiltInElements=wn.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Pt&&(Gt=!1),ht&&(On=!0),ao&&(Ce=Cc({},dRe),Ke=[],ao.html===!0&&(Cc(Ce,fRe),Cc(Ke,gRe)),ao.svg===!0&&(Cc(Ce,a2e),Cc(Ke,u2e),Cc(Ke,mX)),ao.svgFilters===!0&&(Cc(Ce,o2e),Cc(Ke,u2e),Cc(Ke,mX)),ao.mathMl===!0&&(Cc(Ce,c2e),Cc(Ke,pRe),Cc(Ke,mX))),wn.ADD_TAGS&&(Ce===ke&&(Ce=TC(Ce)),Cc(Ce,wn.ADD_TAGS,da)),wn.ADD_ATTR&&(Ke===Ft&&(Ke=TC(Ke)),Cc(Ke,wn.ADD_ATTR,da)),wn.ADD_URI_SAFE_ATTR&&Cc(At,wn.ADD_URI_SAFE_ATTR,da),wn.FORBID_CONTENTS&&(Tr===Fn&&(Tr=TC(Tr)),Cc(Tr,wn.FORBID_CONTENTS,da)),Ma&&(Ce["#text"]=!0),Qe&&Cc(Ce,["html","head","body"]),Ce.table&&(Cc(Ce,["tbody"]),delete gn.tbody),wn.TRUSTED_TYPES_POLICY){if(typeof wn.TRUSTED_TYPES_POLICY.createHTML!="function")throw zF('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof wn.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw zF('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');pe=wn.TRUSTED_TYPES_POLICY,be=pe.createHTML("")}else pe===void 0&&(pe=uPt(F,p)),pe!==null&&typeof be=="string"&&(be=pe.createHTML(""));Ep&&Ep(wn),j0=wn}},Bc=Cc({},["mi","mo","mn","ms","mtext"]),ja=Cc({},["foreignobject","desc","title","annotation-xml"]),Ou=Cc({},["title","style","font","a","script"]),Sa=Cc({},[...a2e,...o2e,...ZNt]),Po=Cc({},[...c2e,...ePt]),Fc=function(wn){let Zr=oe(wn);(!Zr||!Zr.tagName)&&(Zr={namespaceURI:oo,tagName:"template"});const Zi=pX(wn.tagName),nu=pX(Zr.tagName);return $o[wn.namespaceURI]?wn.namespaceURI===fn?Zr.namespaceURI===An?Zi==="svg":Zr.namespaceURI===on?Zi==="svg"&&(nu==="annotation-xml"||Bc[nu]):!!Sa[Zi]:wn.namespaceURI===on?Zr.namespaceURI===An?Zi==="math":Zr.namespaceURI===fn?Zi==="math"&&ja[nu]:!!Po[Zi]:wn.namespaceURI===An?Zr.namespaceURI===fn&&!ja[nu]||Zr.namespaceURI===on&&!Bc[nu]?!1:!Po[Zi]&&(Ou[Zi]||!Sa[Zi]):!!(wo==="application/xhtml+xml"&&$o[wn.namespaceURI]):!1},xa=function(wn){jF(s.removed,{element:wn});try{wn.parentNode.removeChild(wn)}catch{wn.remove()}},Ba=function(wn,Zr){try{jF(s.removed,{attribute:Zr.getAttributeNode(wn),from:Zr})}catch{jF(s.removed,{attribute:null,from:Zr})}if(Zr.removeAttribute(wn),wn==="is"&&!Ke[wn])if(On||ht)try{xa(Zr)}catch{}else try{Zr.setAttribute(wn,"")}catch{}},ga=function(wn){let Zr=null,Zi=null;if(kt)wn=""+wn;else{const Dl=WNt(wn,/^[\r\n\t ]+/);Zi=Dl&&Dl[0]}wo==="application/xhtml+xml"&&oo===An&&(wn=''+wn+"");const nu=pe?pe.createHTML(wn):wn;if(oo===An)try{Zr=new R().parseFromString(nu,wo)}catch{}if(!Zr||!Zr.documentElement){Zr=ae.createDocument(oo,"template",null);try{Zr.documentElement.innerHTML=jo?be:nu}catch{}}const vu=Zr.body||Zr.documentElement;return wn&&Zi&&vu.insertBefore(u.createTextNode(Zi),vu.childNodes[0]||null),oo===An?de.call(Zr,Qe?"html":"body")[0]:Qe?Zr.documentElement:vu},kh=function(wn){return ne.call(wn.ownerDocument||wn,wn,_.SHOW_ELEMENT|_.SHOW_COMMENT|_.SHOW_TEXT,null)},lu=function(wn){return wn instanceof P&&(typeof wn.nodeName!="string"||typeof wn.textContent!="string"||typeof wn.removeChild!="function"||!(wn.attributes instanceof A)||typeof wn.removeAttribute!="function"||typeof wn.setAttribute!="function"||typeof wn.namespaceURI!="string"||typeof wn.insertBefore!="function"||typeof wn.hasChildNodes!="function")},o5=function(wn){return typeof y=="function"&&wn instanceof y},Wh=function(wn,Zr,Zi){ge[wn]&&gX(ge[wn],nu=>{nu.call(s,Zr,Zi,j0)})},od=function(wn){let Zr=null;if(Wh("beforeSanitizeElements",wn,null),lu(wn))return xa(wn),!0;const Zi=da(wn.nodeName);if(Wh("uponSanitizeElement",wn,{tagName:Zi,allowedTags:Ce}),wn.hasChildNodes()&&!o5(wn.firstElementChild)&&im(/<[/\w]/g,wn.innerHTML)&&im(/<[/\w]/g,wn.textContent))return xa(wn),!0;if(!Ce[Zi]||gn[Zi]){if(!gn[Zi]&&cd(Zi)&&(Ne.tagNameCheck instanceof RegExp&&im(Ne.tagNameCheck,Zi)||Ne.tagNameCheck instanceof Function&&Ne.tagNameCheck(Zi)))return!1;if(Ma&&!Tr[Zi]){const nu=oe(wn)||wn.parentNode,vu=ie(wn)||wn.childNodes;if(vu&&nu){const Dl=vu.length;for(let Yh=Dl-1;Yh>=0;--Yh)nu.insertBefore(K(vu[Yh],!0),ee(wn))}}return xa(wn),!0}return wn instanceof T&&!Fc(wn)||(Zi==="noscript"||Zi==="noembed"||Zi==="noframes")&&im(/<\/no(script|embed|frames)/i,wn.innerHTML)?(xa(wn),!0):(Pt&&wn.nodeType===3&&(Zr=wn.textContent,gX([W,xe,U],nu=>{Zr=$F(Zr,nu," ")}),wn.textContent!==Zr&&(jF(s.removed,{element:wn.cloneNode()}),wn.textContent=Zr)),Wh("afterSanitizeElements",wn,null),!1)},Gd=function(wn,Zr,Zi){if(yt&&(Zr==="id"||Zr==="name")&&(Zi in u||Zi in pm))return!1;if(!(Gt&&!_t[Zr]&&im(Fe,Zr))){if(!(Et&&im(Pe,Zr))){if(!Ke[Zr]||_t[Zr]){if(!(cd(wn)&&(Ne.tagNameCheck instanceof RegExp&&im(Ne.tagNameCheck,wn)||Ne.tagNameCheck instanceof Function&&Ne.tagNameCheck(wn))&&(Ne.attributeNameCheck instanceof RegExp&&im(Ne.attributeNameCheck,Zr)||Ne.attributeNameCheck instanceof Function&&Ne.attributeNameCheck(Zr))||Zr==="is"&&Ne.allowCustomizedBuiltInElements&&(Ne.tagNameCheck instanceof RegExp&&im(Ne.tagNameCheck,Zi)||Ne.tagNameCheck instanceof Function&&Ne.tagNameCheck(Zi))))return!1}else if(!At[Zr]){if(!im(Se,$F(Zi,Ie,""))){if(!((Zr==="src"||Zr==="xlink:href"||Zr==="href")&&wn!=="script"&&YNt(Zi,"data:")===0&&qn[wn])){if(!(ln&&!im(je,$F(Zi,Ie,"")))){if(Zi)return!1}}}}}}return!0},cd=function(wn){return wn!=="annotation-xml"&&wn.indexOf("-")>0},Kd=function(wn){Wh("beforeSanitizeAttributes",wn,null);const{attributes:Zr}=wn;if(!Zr)return;const Zi={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ke};let nu=Zr.length;for(;nu--;){const vu=Zr[nu],{name:Dl,namespaceURI:Yh,value:w1}=vu,$0=da(Dl);let Wi=Dl==="value"?w1:XNt(w1);if(Zi.attrName=$0,Zi.attrValue=Wi,Zi.keepAttr=!0,Zi.forceKeepAttr=void 0,Wh("uponSanitizeAttribute",wn,Zi),Wi=Zi.attrValue,Zi.forceKeepAttr||(Ba(Dl,wn),!Zi.keepAttr))continue;if(!xt&&im(/\/>/i,Wi)){Ba(Dl,wn);continue}Pt&&gX([W,xe,U],Qa=>{Wi=$F(Wi,Qa," ")});const Bs=da(wn.nodeName);if(Gd(Bs,$0,Wi)){if(ji&&($0==="id"||$0==="name")&&(Ba(Dl,wn),Wi=xi+Wi),pe&&typeof F=="object"&&typeof F.getAttributeType=="function"&&!Yh)switch(F.getAttributeType(Bs,$0)){case"TrustedHTML":{Wi=pe.createHTML(Wi);break}case"TrustedScriptURL":{Wi=pe.createScriptURL(Wi);break}}try{Yh?wn.setAttributeNS(Yh,Dl,Wi):wn.setAttribute(Dl,Wi),hRe(s.removed)}catch{}}}Wh("afterSanitizeAttributes",wn,null)},$g=function as(wn){let Zr=null;const Zi=kh(wn);for(Wh("beforeSanitizeShadowDOM",wn,null);Zr=Zi.nextNode();)Wh("uponSanitizeShadowNode",Zr,null),!od(Zr)&&(Zr.content instanceof v&&as(Zr.content),Kd(Zr));Wh("afterSanitizeShadowDOM",wn,null)};return s.sanitize=function(as){let wn=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},Zr=null,Zi=null,nu=null,vu=null;if(jo=!as,jo&&(as=""),typeof as!="string"&&!o5(as))if(typeof as.toString=="function"){if(as=as.toString(),typeof as!="string")throw zF("dirty is not a string, aborting")}else throw zF("toString is not a function");if(!s.isSupported)return as;if(Dt||Xc(wn),s.removed=[],typeof as=="string"&&(zs=!1),zs){if(as.nodeName){const w1=da(as.nodeName);if(!Ce[w1]||gn[w1])throw zF("root node is forbidden and cannot be sanitized in-place")}}else if(as instanceof y)Zr=ga(""),Zi=Zr.ownerDocument.importNode(as,!0),Zi.nodeType===1&&Zi.nodeName==="BODY"||Zi.nodeName==="HTML"?Zr=Zi:Zr.appendChild(Zi);else{if(!On&&!Pt&&!Qe&&as.indexOf("<")===-1)return pe&&zr?pe.createHTML(as):as;if(Zr=ga(as),!Zr)return On?null:zr?be:""}Zr&&kt&&xa(Zr.firstChild);const Dl=kh(zs?as:Zr);for(;nu=Dl.nextNode();)od(nu)||(nu.content instanceof v&&$g(nu.content),Kd(nu));if(zs)return as;if(On){if(ht)for(vu=se.call(Zr.ownerDocument);Zr.firstChild;)vu.appendChild(Zr.firstChild);else vu=Zr;return(Ke.shadowroot||Ke.shadowrootmode)&&(vu=X.call(d,vu,!0)),vu}let Yh=Qe?Zr.outerHTML:Zr.innerHTML;return Qe&&Ce["!doctype"]&&Zr.ownerDocument&&Zr.ownerDocument.doctype&&Zr.ownerDocument.doctype.name&&im(mRe,Zr.ownerDocument.doctype.name)&&(Yh=" +`+Yh),Pt&&gX([W,xe,U],w1=>{Yh=$F(Yh,w1," ")}),pe&&zr?pe.createHTML(Yh):Yh},s.setConfig=function(){let as=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Xc(as),Dt=!0},s.clearConfig=function(){j0=null,Dt=!1},s.isValidAttribute=function(as,wn,Zr){j0||Xc({});const Zi=da(as),nu=da(wn);return Gd(Zi,nu,Zr)},s.addHook=function(as,wn){typeof wn=="function"&&(ge[as]=ge[as]||[],jF(ge[as],wn))},s.removeHook=function(as){if(ge[as])return hRe(ge[as])},s.removeHooks=function(as){ge[as]&&(ge[as]=[])},s.removeAllHooks=function(){ge={}},s}var hD=wRe();const fD=//gi,lPt=i=>i?kRe(i).replace(/\\n/g,"#br#").split("#br#"):[""],hPt=(()=>{let i=!1;return()=>{i||(fPt(),i=!0)}})();function fPt(){const i="data-temp-href-target";hD.addHook("beforeSanitizeAttributes",s=>{s.tagName==="A"&&s.hasAttribute("target")&&s.setAttribute(i,s.getAttribute("target")||"")}),hD.addHook("afterSanitizeAttributes",s=>{s.tagName==="A"&&s.hasAttribute(i)&&(s.setAttribute("target",s.getAttribute(i)||""),s.removeAttribute(i),s.getAttribute("target")==="_blank"&&s.setAttribute("rel","noopener"))})}const yRe=i=>(hPt(),hD.sanitize(i)),xRe=(i,s)=>{var u;if(((u=s.flowchart)==null?void 0:u.htmlLabels)!==!1){const d=s.securityLevel;d==="antiscript"||d==="strict"?i=yRe(i):d!=="loose"&&(i=kRe(i),i=i.replace(//g,">"),i=i.replace(/=/g,"="),i=bPt(i))}return i},Yf=(i,s)=>i&&(s.dompurifyConfig?i=hD.sanitize(xRe(i,s),s.dompurifyConfig).toString():i=hD.sanitize(xRe(i,s),{FORBID_TAGS:["style"]}).toString(),i),dPt=(i,s)=>typeof i=="string"?Yf(i,s):i.flat().map(u=>Yf(u,s)),gPt=i=>fD.test(i),pPt=i=>i.split(fD),bPt=i=>i.replace(/#br#/g,"
"),kRe=i=>i.replace(fD,"#br#"),mPt=i=>{let s="";return i&&(s=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,s=s.replaceAll(/\(/g,"\\("),s=s.replaceAll(/\)/g,"\\)")),s},f1=i=>!(i===!1||["false","null","0"].includes(String(i).trim().toLowerCase())),vPt=function(...i){const s=i.filter(u=>!isNaN(u));return Math.max(...s)},wPt=function(...i){const s=i.filter(u=>!isNaN(u));return Math.min(...s)},qF=function(i){const s=i.split(/(,)/),u=[];for(let d=0;d0&&d+1Math.max(0,i.split(s).length-1),yPt=(i,s)=>{const u=l2e(i,"~"),d=l2e(s,"~");return u===1&&d===1},xPt=i=>{const s=l2e(i,"~");let u=!1;if(s<=1)return i;s%2!==0&&i.startsWith("~")&&(i=i.substring(1),u=!0);const d=[...i];let p=d.indexOf("~"),v=d.lastIndexOf("~");for(;p!==-1&&v!==-1&&p!==v;)d[p]="<",d[v]=">",p=d.indexOf("~"),v=d.lastIndexOf("~");return u&&d.unshift("~"),d.join("")},ERe=()=>window.MathMLElement!==void 0,h2e=/\$\$(.*)\$\$/g,Dv=i=>{var s;return(((s=i.match(h2e))==null?void 0:s.length)??0)>0},HF=async(i,s)=>{i=await CC(i,s);const u=document.createElement("div");u.innerHTML=i,u.id="katex-temp",u.style.visibility="hidden",u.style.position="absolute",u.style.top="0";const d=document.querySelector("body");d==null||d.insertAdjacentElement("beforeend",u);const p={width:u.clientWidth,height:u.clientHeight};return u.remove(),p},CC=async(i,s)=>{if(!Dv(i))return i;if(!ERe()&&!s.legacyMathML)return i.replace(h2e,"MathML is unsupported in this environment.");const{default:u}=await Promise.resolve().then(()=>MVt);return i.split(fD).map(d=>Dv(d)?` +
+ ${d} +
+ `:`
${d}
`).join("").replace(h2e,(d,p)=>u.renderToString(p,{throwOnError:!0,displayMode:!0,output:ERe()?"mathml":"htmlAndMathml"}).replace(/\n/g," ").replace(//g,""))},ci={getRows:lPt,sanitizeText:Yf,sanitizeTextOrArray:dPt,hasBreaks:gPt,splitBreaks:pPt,lineBreakRegex:fD,removeScript:yRe,getUrl:mPt,evaluate:f1,getMax:vPt,getMin:wPt},vX={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:i=>i>=255?255:i<0?0:i,g:i=>i>=255?255:i<0?0:i,b:i=>i>=255?255:i<0?0:i,h:i=>i%360,s:i=>i>=100?100:i<0?0:i,l:i=>i>=100?100:i<0?0:i,a:i=>i>=1?1:i<0?0:i},toLinear:i=>{const s=i/255;return i>.03928?Math.pow((s+.055)/1.055,2.4):s/12.92},hue2rgb:(i,s,u)=>(u<0&&(u+=1),u>1&&(u-=1),u<1/6?i+(s-i)*6*u:u<1/2?s:u<2/3?i+(s-i)*(2/3-u)*6:i),hsl2rgb:({h:i,s,l:u},d)=>{if(!s)return u*2.55;i/=360,s/=100,u/=100;const p=u<.5?u*(1+s):u+s-u*s,v=2*u-p;switch(d){case"r":return vX.hue2rgb(v,p,i+1/3)*255;case"g":return vX.hue2rgb(v,p,i)*255;case"b":return vX.hue2rgb(v,p,i-1/3)*255}},rgb2hsl:({r:i,g:s,b:u},d)=>{i/=255,s/=255,u/=255;const p=Math.max(i,s,u),v=Math.min(i,s,u),b=(p+v)/2;if(d==="l")return b*100;if(p===v)return 0;const y=p-v,T=b>.5?y/(2-p-v):y/(p+v);if(d==="s")return T*100;switch(p){case i:return((s-u)/y+(ss>u?Math.min(s,Math.max(u,i)):Math.min(u,Math.max(s,i)),round:i=>Math.round(i*1e10)/1e10},unit:{dec2hex:i=>{const s=Math.round(i).toString(16);return s.length>1?s:`0${s}`}}},v9={};for(let i=0;i<=255;i++)v9[i]=Wa.unit.dec2hex(i);const Og={ALL:0,RGB:1,HSL:2};class kPt{constructor(){this.type=Og.ALL}get(){return this.type}set(s){if(this.type&&this.type!==s)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=s}reset(){this.type=Og.ALL}is(s){return this.type===s}}const EPt=kPt;class TPt{constructor(s,u){this.color=u,this.changed=!1,this.data=s,this.type=new EPt}set(s,u){return this.color=u,this.changed=!1,this.data=s,this.type.type=Og.ALL,this}_ensureHSL(){const s=this.data,{h:u,s:d,l:p}=s;u===void 0&&(s.h=Wa.channel.rgb2hsl(s,"h")),d===void 0&&(s.s=Wa.channel.rgb2hsl(s,"s")),p===void 0&&(s.l=Wa.channel.rgb2hsl(s,"l"))}_ensureRGB(){const s=this.data,{r:u,g:d,b:p}=s;u===void 0&&(s.r=Wa.channel.hsl2rgb(s,"r")),d===void 0&&(s.g=Wa.channel.hsl2rgb(s,"g")),p===void 0&&(s.b=Wa.channel.hsl2rgb(s,"b"))}get r(){const s=this.data,u=s.r;return!this.type.is(Og.HSL)&&u!==void 0?u:(this._ensureHSL(),Wa.channel.hsl2rgb(s,"r"))}get g(){const s=this.data,u=s.g;return!this.type.is(Og.HSL)&&u!==void 0?u:(this._ensureHSL(),Wa.channel.hsl2rgb(s,"g"))}get b(){const s=this.data,u=s.b;return!this.type.is(Og.HSL)&&u!==void 0?u:(this._ensureHSL(),Wa.channel.hsl2rgb(s,"b"))}get h(){const s=this.data,u=s.h;return!this.type.is(Og.RGB)&&u!==void 0?u:(this._ensureRGB(),Wa.channel.rgb2hsl(s,"h"))}get s(){const s=this.data,u=s.s;return!this.type.is(Og.RGB)&&u!==void 0?u:(this._ensureRGB(),Wa.channel.rgb2hsl(s,"s"))}get l(){const s=this.data,u=s.l;return!this.type.is(Og.RGB)&&u!==void 0?u:(this._ensureRGB(),Wa.channel.rgb2hsl(s,"l"))}get a(){return this.data.a}set r(s){this.type.set(Og.RGB),this.changed=!0,this.data.r=s}set g(s){this.type.set(Og.RGB),this.changed=!0,this.data.g=s}set b(s){this.type.set(Og.RGB),this.changed=!0,this.data.b=s}set h(s){this.type.set(Og.HSL),this.changed=!0,this.data.h=s}set s(s){this.type.set(Og.HSL),this.changed=!0,this.data.s=s}set l(s){this.type.set(Og.HSL),this.changed=!0,this.data.l=s}set a(s){this.changed=!0,this.data.a=s}}const CPt=TPt,wX=new CPt({r:0,g:0,b:0,a:0},"transparent"),TRe={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:i=>{if(i.charCodeAt(0)!==35)return;const s=i.match(TRe.re);if(!s)return;const u=s[1],d=parseInt(u,16),p=u.length,v=p%4===0,b=p>4,y=b?1:17,T=b?8:4,_=v?0:-1,A=b?255:15;return wX.set({r:(d>>T*(_+3)&A)*y,g:(d>>T*(_+2)&A)*y,b:(d>>T*(_+1)&A)*y,a:v?(d&A)*y/255:1},i)},stringify:i=>{const{r:s,g:u,b:d,a:p}=i;return p<1?`#${v9[Math.round(s)]}${v9[Math.round(u)]}${v9[Math.round(d)]}${v9[Math.round(p*255)]}`:`#${v9[Math.round(s)]}${v9[Math.round(u)]}${v9[Math.round(d)]}`}},VF=TRe,yX={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:i=>{const s=i.match(yX.hueRe);if(s){const[,u,d]=s;switch(d){case"grad":return Wa.channel.clamp.h(parseFloat(u)*.9);case"rad":return Wa.channel.clamp.h(parseFloat(u)*180/Math.PI);case"turn":return Wa.channel.clamp.h(parseFloat(u)*360)}}return Wa.channel.clamp.h(parseFloat(i))},parse:i=>{const s=i.charCodeAt(0);if(s!==104&&s!==72)return;const u=i.match(yX.re);if(!u)return;const[,d,p,v,b,y]=u;return wX.set({h:yX._hue2deg(d),s:Wa.channel.clamp.s(parseFloat(p)),l:Wa.channel.clamp.l(parseFloat(v)),a:b?Wa.channel.clamp.a(y?parseFloat(b)/100:parseFloat(b)):1},i)},stringify:i=>{const{h:s,s:u,l:d,a:p}=i;return p<1?`hsla(${Wa.lang.round(s)}, ${Wa.lang.round(u)}%, ${Wa.lang.round(d)}%, ${p})`:`hsl(${Wa.lang.round(s)}, ${Wa.lang.round(u)}%, ${Wa.lang.round(d)}%)`}},xX=yX,kX={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:i=>{i=i.toLowerCase();const s=kX.colors[i];if(s)return VF.parse(s)},stringify:i=>{const s=VF.stringify(i);for(const u in kX.colors)if(kX.colors[u]===s)return u}},CRe=kX,SRe={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:i=>{const s=i.charCodeAt(0);if(s!==114&&s!==82)return;const u=i.match(SRe.re);if(!u)return;const[,d,p,v,b,y,T,_,A]=u;return wX.set({r:Wa.channel.clamp.r(p?parseFloat(d)*2.55:parseFloat(d)),g:Wa.channel.clamp.g(b?parseFloat(v)*2.55:parseFloat(v)),b:Wa.channel.clamp.b(T?parseFloat(y)*2.55:parseFloat(y)),a:_?Wa.channel.clamp.a(A?parseFloat(_)/100:parseFloat(_)):1},i)},stringify:i=>{const{r:s,g:u,b:d,a:p}=i;return p<1?`rgba(${Wa.lang.round(s)}, ${Wa.lang.round(u)}, ${Wa.lang.round(d)}, ${Wa.lang.round(p)})`:`rgb(${Wa.lang.round(s)}, ${Wa.lang.round(u)}, ${Wa.lang.round(d)})`}},EX=SRe,O3={format:{keyword:CRe,hex:VF,rgb:EX,rgba:EX,hsl:xX,hsla:xX},parse:i=>{if(typeof i!="string")return i;const s=VF.parse(i)||EX.parse(i)||xX.parse(i)||CRe.parse(i);if(s)return s;throw new Error(`Unsupported color format: "${i}"`)},stringify:i=>!i.changed&&i.color?i.color:i.type.is(Og.HSL)||i.data.r===void 0?xX.stringify(i):i.a<1||!Number.isInteger(i.r)||!Number.isInteger(i.g)||!Number.isInteger(i.b)?EX.stringify(i):VF.stringify(i)},_Re=(i,s)=>{const u=O3.parse(i);for(const d in s)u[d]=Wa.channel.clamp[d](s[d]);return O3.stringify(u)},SC=(i,s,u=0,d=1)=>{if(typeof i!="number")return _Re(i,{a:s});const p=wX.set({r:Wa.channel.clamp.r(i),g:Wa.channel.clamp.g(s),b:Wa.channel.clamp.b(u),a:Wa.channel.clamp.a(d)});return O3.stringify(p)},ARe=(i,s)=>Wa.lang.round(O3.parse(i)[s]),SPt=i=>{const{r:s,g:u,b:d}=O3.parse(i),p=.2126*Wa.channel.toLinear(s)+.7152*Wa.channel.toLinear(u)+.0722*Wa.channel.toLinear(d);return Wa.lang.round(p)},_Pt=i=>SPt(i)>=.5,_C=i=>!_Pt(i),LRe=(i,s,u)=>{const d=O3.parse(i),p=d[s],v=Wa.channel.clamp[s](p+u);return p!==v&&(d[s]=v),O3.stringify(d)},Gs=(i,s)=>LRe(i,"l",s),fa=(i,s)=>LRe(i,"l",-s),In=(i,s)=>{const u=O3.parse(i),d={};for(const p in s)s[p]&&(d[p]=u[p]+s[p]);return _Re(i,d)},APt=(i,s,u=50)=>{const{r:d,g:p,b:v,a:b}=O3.parse(i),{r:y,g:T,b:_,a:A}=O3.parse(s),P=u/100,R=P*2-1,F=b-A,K=((R*F===-1?R:(R+F)/(1+R*F))+1)/2,ee=1-K,ie=d*K+y*ee,oe=p*K+T*ee,pe=v*K+_*ee,be=b*P+A*(1-P);return SC(ie,oe,pe,be)},Vi=(i,s=100)=>{const u=O3.parse(i);return u.r=255-u.r,u.g=255-u.g,u.b=255-u.b,APt(u,i,s)},Tp=(i,s)=>s?In(i,{s:-40,l:10}):In(i,{s:-40,l:-10}),TX="#ffffff",CX="#f2f2f2";let LPt=class{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(){var u,d,p,v,b,y,T,_,A,P,R;if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||In(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||In(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||Tp(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||Tp(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||Tp(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||Tp(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||Vi(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||Vi(this.tertiaryColor),this.lineColor=this.lineColor||Vi(this.background),this.arrowheadColor=this.arrowheadColor||Vi(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?fa(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||"grey",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||fa(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||Vi(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||Gs(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.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||In(this.primaryColor,{h:30}),this.cScale4=this.cScale4||In(this.primaryColor,{h:60}),this.cScale5=this.cScale5||In(this.primaryColor,{h:90}),this.cScale6=this.cScale6||In(this.primaryColor,{h:120}),this.cScale7=this.cScale7||In(this.primaryColor,{h:150}),this.cScale8=this.cScale8||In(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||In(this.primaryColor,{h:270}),this.cScale10=this.cScale10||In(this.primaryColor,{h:300}),this.cScale11=this.cScale11||In(this.primaryColor,{h:330}),this.darkMode)for(let F=0;F{this[d]=s[d]}),this.updateColors(),u.forEach(d=>{this[d]=s[d]})}};const MPt=i=>{const s=new LPt;return s.calculate(i),s};let DPt=class{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=Gs(this.primaryColor,16),this.tertiaryColor=In(this.primaryColor,{h:-160}),this.primaryBorderColor=Vi(this.background),this.secondaryBorderColor=Tp(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Tp(this.tertiaryColor,this.darkMode),this.primaryTextColor=Vi(this.primaryColor),this.secondaryTextColor=Vi(this.secondaryColor),this.tertiaryTextColor=Vi(this.tertiaryColor),this.lineColor=Vi(this.background),this.textColor=Vi(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=Gs(Vi("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=SC(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=fa("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=fa(this.sectionBkgColor,10),this.taskBorderColor=SC(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=SC(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.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){var s,u,d,p,v,b,y,T,_,A,P;this.secondBkg=Gs(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=Gs(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.mainContrastColor,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=Gs(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.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=In(this.primaryColor,{h:64}),this.fillType3=In(this.secondaryColor,{h:64}),this.fillType4=In(this.primaryColor,{h:-64}),this.fillType5=In(this.secondaryColor,{h:-64}),this.fillType6=In(this.primaryColor,{h:128}),this.fillType7=In(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||In(this.primaryColor,{h:30}),this.cScale4=this.cScale4||In(this.primaryColor,{h:60}),this.cScale5=this.cScale5||In(this.primaryColor,{h:90}),this.cScale6=this.cScale6||In(this.primaryColor,{h:120}),this.cScale7=this.cScale7||In(this.primaryColor,{h:150}),this.cScale8=this.cScale8||In(this.primaryColor,{h:210}),this.cScale9=this.cScale9||In(this.primaryColor,{h:270}),this.cScale10=this.cScale10||In(this.primaryColor,{h:300}),this.cScale11=this.cScale11||In(this.primaryColor,{h:330});for(let R=0;R{this[d]=s[d]}),this.updateColors(),u.forEach(d=>{this[d]=s[d]})}};const IPt=i=>{const s=new DPt;return s.calculate(i),s};let OPt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=In(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=In(this.primaryColor,{h:-160}),this.primaryBorderColor=Tp(this.primaryColor,this.darkMode),this.secondaryBorderColor=Tp(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Tp(this.tertiaryColor,this.darkMode),this.primaryTextColor=Vi(this.primaryColor),this.secondaryTextColor=Vi(this.secondaryColor),this.tertiaryTextColor=Vi(this.tertiaryColor),this.lineColor=Vi(this.background),this.textColor=Vi(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="#e8e8e8",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="grey",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=SC(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.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){var s,u,d,p,v,b,y,T,_,A,P;this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||In(this.primaryColor,{h:30}),this.cScale4=this.cScale4||In(this.primaryColor,{h:60}),this.cScale5=this.cScale5||In(this.primaryColor,{h:90}),this.cScale6=this.cScale6||In(this.primaryColor,{h:120}),this.cScale7=this.cScale7||In(this.primaryColor,{h:150}),this.cScale8=this.cScale8||In(this.primaryColor,{h:210}),this.cScale9=this.cScale9||In(this.primaryColor,{h:270}),this.cScale10=this.cScale10||In(this.primaryColor,{h:300}),this.cScale11=this.cScale11||In(this.primaryColor,{h:330}),this["cScalePeer1"]=this["cScalePeer1"]||fa(this.secondaryColor,45),this["cScalePeer2"]=this["cScalePeer2"]||fa(this.tertiaryColor,40);for(let R=0;R{this[d]=s[d]}),this.updateColors(),u.forEach(d=>{this[d]=s[d]})}};const f2e=i=>{const s=new OPt;return s.calculate(i),s};let NPt=class{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=Gs("#cde498",10),this.primaryBorderColor=Tp(this.primaryColor,this.darkMode),this.secondaryBorderColor=Tp(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Tp(this.tertiaryColor,this.darkMode),this.primaryTextColor=Vi(this.primaryColor),this.secondaryTextColor=Vi(this.secondaryColor),this.tertiaryTextColor=Vi(this.primaryColor),this.lineColor=Vi(this.background),this.textColor=Vi(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="grey",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.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var s,u,d,p,v,b,y,T,_,A,P;this.actorBorder=fa(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.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||In(this.primaryColor,{h:30}),this.cScale4=this.cScale4||In(this.primaryColor,{h:60}),this.cScale5=this.cScale5||In(this.primaryColor,{h:90}),this.cScale6=this.cScale6||In(this.primaryColor,{h:120}),this.cScale7=this.cScale7||In(this.primaryColor,{h:150}),this.cScale8=this.cScale8||In(this.primaryColor,{h:210}),this.cScale9=this.cScale9||In(this.primaryColor,{h:270}),this.cScale10=this.cScale10||In(this.primaryColor,{h:300}),this.cScale11=this.cScale11||In(this.primaryColor,{h:330}),this["cScalePeer1"]=this["cScalePeer1"]||fa(this.secondaryColor,45),this["cScalePeer2"]=this["cScalePeer2"]||fa(this.tertiaryColor,40);for(let R=0;R{this[d]=s[d]}),this.updateColors(),u.forEach(d=>{this[d]=s[d]})}};const PPt=i=>{const s=new NPt;return s.calculate(i),s};class BPt{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=Gs(this.contrast,55),this.background="#ffffff",this.tertiaryColor=In(this.primaryColor,{h:-160}),this.primaryBorderColor=Tp(this.primaryColor,this.darkMode),this.secondaryBorderColor=Tp(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Tp(this.tertiaryColor,this.darkMode),this.primaryTextColor=Vi(this.primaryColor),this.secondaryTextColor=Vi(this.secondaryColor),this.tertiaryTextColor=Vi(this.tertiaryColor),this.lineColor=Vi(this.background),this.textColor=Vi(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="calculated",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.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var s,u,d,p,v,b,y,T,_,A,P;this.secondBkg=Gs(this.contrast,55),this.border2=this.contrast,this.actorBorder=Gs(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.lineColor,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 R=0;R{this[d]=s[d]}),this.updateColors(),u.forEach(d=>{this[d]=s[d]})}}const E7={base:{getThemeVariables:MPt},dark:{getThemeVariables:IPt},default:{getThemeVariables:f2e},forest:{getThemeVariables:PPt},neutral:{getThemeVariables:i=>{const s=new BPt;return s.calculate(i),s}}},T7={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},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,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},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},theme:"default",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","maxEdges"],legacyMathML:!1,deterministicIds:!1,fontSize:16},MRe={...T7,deterministicIDSeed:void 0,themeCSS:void 0,themeVariables:E7.default.getThemeVariables(),sequence:{...T7.sequence,messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},noteFont:function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},actorFont:function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}},gantt:{...T7.gantt,tickInterval:void 0,useWidth:void 0},c4:{...T7.c4,useWidth:void 0,personFont:function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},external_personFont:function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},systemFont:function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},external_systemFont:function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},system_dbFont:function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},external_system_dbFont:function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},system_queueFont:function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},external_system_queueFont:function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},containerFont:function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},external_containerFont:function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},container_dbFont:function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},external_container_dbFont:function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},container_queueFont:function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},external_container_queueFont:function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},componentFont:function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},external_componentFont:function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},component_dbFont:function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},external_component_dbFont:function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},component_queueFont:function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},external_component_queueFont:function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},boundaryFont:function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}},pie:{...T7.pie,useWidth:984},xyChart:{...T7.xyChart,useWidth:void 0},requirement:{...T7.requirement,useWidth:void 0},gitGraph:{...T7.gitGraph,useMaxWidth:!1},sankey:{...T7.sankey,useMaxWidth:!1}},DRe=(i,s="")=>Object.keys(i).reduce((u,d)=>Array.isArray(i[d])?u:typeof i[d]=="object"&&i[d]!==null?[...u,s+d,...DRe(i[d],"")]:[...u,s+d],[]),FPt=new Set(DRe(MRe,"")),sh=MRe,SX=i=>{if(Xe.debug("sanitizeDirective called with",i),!(typeof i!="object"||i==null)){if(Array.isArray(i)){i.forEach(s=>SX(s));return}for(const s of Object.keys(i)){if(Xe.debug("Checking key",s),s.startsWith("__")||s.includes("proto")||s.includes("constr")||!FPt.has(s)||i[s]==null){Xe.debug("sanitize deleting key: ",s),delete i[s];continue}if(typeof i[s]=="object"){Xe.debug("sanitizing object",s),SX(i[s]);continue}const u=["themeCSS","fontFamily","altFontFamily"];for(const d of u)s.includes(d)&&(Xe.debug("sanitizing css option",s),i[s]=RPt(i[s]))}if(i.themeVariables)for(const s of Object.keys(i.themeVariables)){const u=i.themeVariables[s];u!=null&&u.match&&!u.match(/^[\d "#%(),.;A-Za-z]+$/)&&(i.themeVariables[s]="")}Xe.debug("After sanitization",i)}},RPt=i=>{let s=0,u=0;for(const d of i){if(s{for(const{id:s,detector:u,loader:d}of i)PRe(s,u,d)},PRe=(i,s,u)=>{dD[i]?Xe.error(`Detector with key ${i} already exists`):dD[i]={detector:s,loader:u},Xe.debug(`Detector with key ${i} added${u?" with loader":""}`)},$Pt=i=>dD[i].loader,d2e=(i,s,{depth:u=2,clobber:d=!1}={})=>{const p={depth:u,clobber:d};return Array.isArray(s)&&!Array.isArray(i)?(s.forEach(v=>d2e(i,v,p)),i):Array.isArray(s)&&Array.isArray(i)?(s.forEach(v=>{i.includes(v)||i.push(v)}),i):i===void 0||u<=0?i!=null&&typeof i=="object"&&typeof s=="object"?Object.assign(i,s):s:(s!==void 0&&typeof i=="object"&&typeof s=="object"&&Object.keys(s).forEach(v=>{typeof s[v]=="object"&&(i[v]===void 0||typeof i[v]=="object")?(i[v]===void 0&&(i[v]=Array.isArray(s[v])?[]:{}),i[v]=d2e(i[v],s[v],{depth:u-1,clobber:d})):(d||typeof i[v]!="object"&&typeof s[v]!="object")&&(i[v]=s[v])}),i)},id=d2e;var zPt=typeof global=="object"&&global&&global.Object===Object&&global;const BRe=zPt;var qPt=typeof self=="object"&&self&&self.Object===Object&&self,HPt=BRe||qPt||Function("return this")();const N3=HPt;var VPt=N3.Symbol;const Iv=VPt;var FRe=Object.prototype,UPt=FRe.hasOwnProperty,GPt=FRe.toString,GF=Iv?Iv.toStringTag:void 0;function KPt(i){var s=UPt.call(i,GF),u=i[GF];try{i[GF]=void 0;var d=!0}catch{}var p=GPt.call(i);return d&&(s?i[GF]=u:delete i[GF]),p}var WPt=Object.prototype,YPt=WPt.toString;function XPt(i){return YPt.call(i)}var QPt="[object Null]",JPt="[object Undefined]",RRe=Iv?Iv.toStringTag:void 0;function AC(i){return i==null?i===void 0?JPt:QPt:RRe&&RRe in Object(i)?KPt(i):XPt(i)}function am(i){var s=typeof i;return i!=null&&(s=="object"||s=="function")}var ZPt="[object AsyncFunction]",eBt="[object Function]",tBt="[object GeneratorFunction]",nBt="[object Proxy]";function gD(i){if(!am(i))return!1;var s=AC(i);return s==eBt||s==tBt||s==ZPt||s==nBt}var rBt=N3["__core-js_shared__"];const g2e=rBt;var jRe=function(){var i=/[^.]+$/.exec(g2e&&g2e.keys&&g2e.keys.IE_PROTO||"");return i?"Symbol(src)_1."+i:""}();function iBt(i){return!!jRe&&jRe in i}var sBt=Function.prototype,aBt=sBt.toString;function LC(i){if(i!=null){try{return aBt.call(i)}catch{}try{return i+""}catch{}}return""}var oBt=/[\\^$.*+?()[\]{}|]/g,cBt=/^\[object .+?Constructor\]$/,uBt=Function.prototype,lBt=Object.prototype,hBt=uBt.toString,fBt=lBt.hasOwnProperty,dBt=RegExp("^"+hBt.call(fBt).replace(oBt,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function gBt(i){if(!am(i)||iBt(i))return!1;var s=gD(i)?dBt:cBt;return s.test(LC(i))}function pBt(i,s){return i==null?void 0:i[s]}function MC(i,s){var u=pBt(i,s);return gBt(u)?u:void 0}var bBt=MC(Object,"create");const KF=bBt;function mBt(){this.__data__=KF?KF(null):{},this.size=0}function vBt(i){var s=this.has(i)&&delete this.__data__[i];return this.size-=s?1:0,s}var wBt="__lodash_hash_undefined__",yBt=Object.prototype,xBt=yBt.hasOwnProperty;function kBt(i){var s=this.__data__;if(KF){var u=s[i];return u===wBt?void 0:u}return xBt.call(s,i)?s[i]:void 0}var EBt=Object.prototype,TBt=EBt.hasOwnProperty;function CBt(i){var s=this.__data__;return KF?s[i]!==void 0:TBt.call(s,i)}var SBt="__lodash_hash_undefined__";function _Bt(i,s){var u=this.__data__;return this.size+=this.has(i)?0:1,u[i]=KF&&s===void 0?SBt:s,this}function DC(i){var s=-1,u=i==null?0:i.length;for(this.clear();++s-1}function NBt(i,s){var u=this.__data__,d=AX(u,i);return d<0?(++this.size,u.push([i,s])):u[d][1]=s,this}function C7(i){var s=-1,u=i==null?0:i.length;for(this.clear();++s-1&&i%1==0&&i<=uFt}function w9(i){return i!=null&&w2e(i.length)&&!gD(i)}function JRe(i){return q4(i)&&w9(i)}function lFt(){return!1}var ZRe=typeof exports=="object"&&exports&&!exports.nodeType&&exports,eje=ZRe&&typeof module=="object"&&module&&!module.nodeType&&module,hFt=eje&&eje.exports===ZRe,tje=hFt?N3.Buffer:void 0,fFt=tje?tje.isBuffer:void 0,dFt=fFt||lFt;const vD=dFt;var gFt="[object Object]",pFt=Function.prototype,bFt=Object.prototype,nje=pFt.toString,mFt=bFt.hasOwnProperty,vFt=nje.call(Object);function rje(i){if(!q4(i)||AC(i)!=gFt)return!1;var s=v2e(i);if(s===null)return!0;var u=mFt.call(s,"constructor")&&s.constructor;return typeof u=="function"&&u instanceof u&&nje.call(u)==vFt}var wFt="[object Arguments]",yFt="[object Array]",xFt="[object Boolean]",kFt="[object Date]",EFt="[object Error]",TFt="[object Function]",CFt="[object Map]",SFt="[object Number]",_Ft="[object Object]",AFt="[object RegExp]",LFt="[object Set]",MFt="[object String]",DFt="[object WeakMap]",IFt="[object ArrayBuffer]",OFt="[object DataView]",NFt="[object Float32Array]",PFt="[object Float64Array]",BFt="[object Int8Array]",FFt="[object Int16Array]",RFt="[object Int32Array]",jFt="[object Uint8Array]",$Ft="[object Uint8ClampedArray]",zFt="[object Uint16Array]",qFt="[object Uint32Array]",ah={};ah[NFt]=ah[PFt]=ah[BFt]=ah[FFt]=ah[RFt]=ah[jFt]=ah[$Ft]=ah[zFt]=ah[qFt]=!0,ah[wFt]=ah[yFt]=ah[IFt]=ah[xFt]=ah[OFt]=ah[kFt]=ah[EFt]=ah[TFt]=ah[CFt]=ah[SFt]=ah[_Ft]=ah[AFt]=ah[LFt]=ah[MFt]=ah[DFt]=!1;function HFt(i){return q4(i)&&w2e(i.length)&&!!ah[AC(i)]}function NX(i){return function(s){return i(s)}}var ije=typeof exports=="object"&&exports&&!exports.nodeType&&exports,YF=ije&&typeof module=="object"&&module&&!module.nodeType&&module,VFt=YF&&YF.exports===ije,y2e=VFt&&BRe.process,UFt=function(){try{var i=YF&&YF.require&&YF.require("util").types;return i||y2e&&y2e.binding&&y2e.binding("util")}catch{}}();const wD=UFt;var sje=wD&&wD.isTypedArray,GFt=sje?NX(sje):HFt;const PX=GFt;function x2e(i,s){if(!(s==="constructor"&&typeof i[s]=="function")&&s!="__proto__")return i[s]}var KFt=Object.prototype,WFt=KFt.hasOwnProperty;function BX(i,s,u){var d=i[s];(!(WFt.call(i,s)&&pD(d,u))||u===void 0&&!(s in i))&&DX(i,s,u)}function XF(i,s,u,d){var p=!u;u||(u={});for(var v=-1,b=s.length;++v-1&&i%1==0&&i0){if(++s>=uRt)return arguments[0]}else s=0;return i.apply(void 0,arguments)}}var dRt=fRt(cRt);const lje=dRt;function RX(i,s){return lje(uje(i,s,OC),i+"")}function QF(i,s,u){if(!am(u))return!1;var d=typeof s;return(d=="number"?w9(u)&&FX(s,u.length):d=="string"&&s in u)?pD(u[s],i):!1}function gRt(i){return RX(function(s,u){var d=-1,p=u.length,v=p>1?u[p-1]:void 0,b=p>2?u[2]:void 0;for(v=i.length>3&&typeof v=="function"?(p--,v):void 0,b&&QF(u[0],u[1],b)&&(v=p<3?void 0:v,p=1),s=Object(s);++dy.args);SX(b),d=id(d,[...b])}else d=u.args;if(!d)return;let p=_X(i,s);const v="config";return d[v]!==void 0&&(p==="flowchart-v2"&&(p="flowchart"),d[p]=d[v],delete d[v]),d},fje=function(i,s=null){try{const u=new RegExp(`[%]{2}(?![{]${mRt.source})(?=[}][%]{2}).* +`,"ig");i=i.trim().replace(u,"").replace(/'/gm,'"'),Xe.debug(`Detecting diagram directive${s!==null?" type:"+s:""} based on the text:${i}`);let d;const p=[];for(;(d=UF.exec(i))!==null;)if(d.index===UF.lastIndex&&UF.lastIndex++,d&&!s||s&&d[1]&&d[1].match(s)||s&&d[2]&&d[2].match(s)){const v=d[1]?d[1]:d[2],b=d[3]?d[3].trim():d[4]?JSON.parse(d[4].trim()):null;p.push({type:v,args:b})}return p.length===0?{type:i,args:null}:p.length===1?p[0]:p}catch(u){return Xe.error(`ERROR: ${u.message} - Unable to parse directive type: '${s}' based on the text: '${i}'`),{type:void 0,args:null}}},wRt=function(i){return i.replace(UF,"")},yRt=function(i,s){for(const[u,d]of s.entries())if(d.match(i))return u;return-1};function Ov(i,s){if(!i)return s;const u=`curve${i.charAt(0).toUpperCase()+i.slice(1)}`;return bRt[u]??s}function xRt(i,s){const u=i.trim();if(u)return s.securityLevel!=="loose"?p9.sanitizeUrl(u):u}const kRt=(i,...s)=>{const u=i.split("."),d=u.length-1,p=u[d];let v=window;for(let b=0;b{u+=dje(p,s),s=p});const d=u/2;return k2e(i,d)}function TRt(i){return i.length===1?i[0]:ERt(i)}const gje=(i,s=2)=>{const u=Math.pow(10,s);return Math.round(i*u)/u},k2e=(i,s)=>{let u,d=s;for(const p of i){if(u){const v=dje(p,u);if(v=1)return{x:p.x,y:p.y};if(b>0&&b<1)return{x:gje((1-b)*u.x+b*p.x,5),y:gje((1-b)*u.y+b*p.y,5)}}}u=p}throw new Error("Could not find a suitable point for the given distance")},CRt=(i,s,u)=>{Xe.info(`our points ${JSON.stringify(s)}`),s[0]!==u&&(s=s.reverse());const p=k2e(s,25),v=i?10:5,b=Math.atan2(s[0].y-p.y,s[0].x-p.x),y={x:0,y:0};return y.x=Math.sin(b)*v+(s[0].x+p.x)/2,y.y=-Math.cos(b)*v+(s[0].y+p.y)/2,y};function SRt(i,s,u){const d=structuredClone(u);Xe.info("our points",d),s!=="start_left"&&s!=="start_right"&&d.reverse();const p=25+i,v=k2e(d,p),b=10+i*.5,y=Math.atan2(d[0].y-v.y,d[0].x-v.x),T={x:0,y:0};return s==="start_left"?(T.x=Math.sin(y+Math.PI)*b+(d[0].x+v.x)/2,T.y=-Math.cos(y+Math.PI)*b+(d[0].y+v.y)/2):s==="end_right"?(T.x=Math.sin(y-Math.PI)*b+(d[0].x+v.x)/2-5,T.y=-Math.cos(y-Math.PI)*b+(d[0].y+v.y)/2-5):s==="end_left"?(T.x=Math.sin(y)*b+(d[0].x+v.x)/2-5,T.y=-Math.cos(y)*b+(d[0].y+v.y)/2-5):(T.x=Math.sin(y)*b+(d[0].x+v.x)/2,T.y=-Math.cos(y)*b+(d[0].y+v.y)/2),T}function om(i){let s="",u="";for(const d of i)d!==void 0&&(d.startsWith("color:")||d.startsWith("text-align:")?u=u+d+";":s=s+d+";");return{style:s,labelStyle:u}}let pje=0;const bje=()=>(pje++,"id-"+Math.random().toString(36).substr(2,12)+"-"+pje);function _Rt(i){let s="";const u="0123456789abcdef",d=u.length;for(let p=0;p_Rt(i.length),ARt=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:""}},LRt=function(i,s){const u=s.text.replace(ci.lineBreakRegex," "),[,d]=NC(s.fontSize),p=i.append("text");p.attr("x",s.x),p.attr("y",s.y),p.style("text-anchor",s.anchor),p.style("font-family",s.fontFamily),p.style("font-size",d),p.style("font-weight",s.fontWeight),p.attr("fill",s.fill),s.class!==void 0&&p.attr("class",s.class);const v=p.append("tspan");return v.attr("x",s.x+s.textMargin*2),v.attr("fill",s.fill),v.text(u),p},vje=bD((i,s,u)=>{if(!i||(u=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
"},u),ci.lineBreakRegex.test(i)))return i;const d=i.split(" "),p=[];let v="";return d.forEach((b,y)=>{const T=H4(`${b} `,u),_=H4(v,u);if(T>s){const{hyphenatedStrings:R,remainingWord:F}=MRt(b,s,"-",u);p.push(v,...R),v=F}else _+T>=s?(p.push(v),v=b):v=[v,b].filter(Boolean).join(" ");y+1===d.length&&p.push(v)}),p.filter(b=>b!=="").join(u.joinWith)},(i,s,u)=>`${i}${s}${u.fontSize}${u.fontWeight}${u.fontFamily}${u.joinWith}`),MRt=bD((i,s,u="-",d)=>{d=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},d);const p=[...i],v=[];let b="";return p.forEach((y,T)=>{const _=`${b}${y}`;if(H4(_,d)>=s){const P=T+1,R=p.length===P,F=`${_}${u}`;v.push(R?_:F),b=""}else b=_}),{hyphenatedStrings:v,remainingWord:b}},(i,s,u="-",d)=>`${i}${s}${u}${d.fontSize}${d.fontWeight}${d.fontFamily}`);function E2e(i,s){return T2e(i,s).height}function H4(i,s){return T2e(i,s).width}const T2e=bD((i,s)=>{const{fontSize:u=12,fontFamily:d="Arial",fontWeight:p=400}=s;if(!i)return{width:0,height:0};const[,v]=NC(u),b=["sans-serif",d],y=i.split(ci.lineBreakRegex),T=[],_=Ir("body");if(!_.remove)return{width:0,height:0,lineHeight:0};const A=_.append("svg");for(const R of b){let F=0;const j={width:0,height:0,lineHeight:0};for(const K of y){const ee=ARt();ee.text=K||hje;const ie=LRt(A,ee).style("font-size",v).style("font-weight",p).style("font-family",R),oe=(ie._groups||ie)[0][0].getBBox();if(oe.width===0&&oe.height===0)throw new Error("svg element not in render tree");j.width=Math.round(Math.max(j.width,oe.width)),F=Math.round(oe.height),j.height+=F,j.lineHeight=Math.round(Math.max(j.lineHeight,F))}T.push(j)}A.remove();const P=isNaN(T[1].height)||isNaN(T[1].width)||isNaN(T[1].lineHeight)||T[0].height>T[1].height&&T[0].width>T[1].width&&T[0].lineHeight>T[1].lineHeight?0:1;return T[P]},(i,s)=>`${i}${s.fontSize}${s.fontWeight}${s.fontFamily}`);class DRt{constructor(s=!1,u){this.count=0,this.count=u?u.length:0,this.next=s?()=>this.count++:()=>Date.now()}}let $X;const IRt=function(i){return $X=$X||document.createElement("div"),i=escape(i).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),$X.innerHTML=i,unescape($X.textContent)};function wje(i){return"str"in i}const ORt=(i,s,u,d)=>{var v;if(!d)return;const p=(v=i.node())==null?void 0:v.getBBox();p&&i.append("text").text(d).attr("x",p.x+p.width/2).attr("y",-u).attr("class",s)},NC=i=>{if(typeof i=="number")return[i,i+"px"];const s=parseInt(i??"",10);return Number.isNaN(s)?[void 0,void 0]:i===String(s)?[s,i+"px"]:[s,i]};function JF(i,s){return jX({},i,s)}const Ao={assignWithDepth:id,wrapLabel:vje,calculateTextHeight:E2e,calculateTextWidth:H4,calculateTextDimensions:T2e,cleanAndMerge:JF,detectInit:vRt,detectDirective:fje,isSubstringInArray:yRt,interpolateToCurve:Ov,calcLabelPosition:TRt,calcCardinalityPosition:CRt,calcTerminalLabelPosition:SRt,formatUrl:xRt,getStylesFromArray:om,generateId:bje,random:mje,runFunc:kRt,entityDecode:IRt,insertTitle:ORt,parseFontSize:NC,InitIDGenerator:DRt},NRt=function(i){let s=i;return s=s.replace(/style.*:\S*#.*;/g,function(u){return u.substring(0,u.length-1)}),s=s.replace(/classDef.*:\S*#.*;/g,function(u){return u.substring(0,u.length-1)}),s=s.replace(/#\w+;/g,function(u){const d=u.substring(1,u.length-1);return/^\+?\d+$/.test(d)?"fl°°"+d+"¶ß":"fl°"+d+"¶ß"}),s},ZF=function(i){return i.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")};var yje="comm",xje="rule",kje="decl",PRt="@import",BRt="@keyframes",FRt="@layer",Eje=Math.abs,C2e=String.fromCharCode;function Tje(i){return i.trim()}function zX(i,s,u){return i.replace(s,u)}function RRt(i,s,u){return i.indexOf(s,u)}function eR(i,s){return i.charCodeAt(s)|0}function tR(i,s,u){return i.slice(s,u)}function _7(i){return i.length}function jRt(i){return i.length}function qX(i,s){return s.push(i),i}var HX=1,xD=1,Cje=0,Nv=0,I0=0,kD="";function S2e(i,s,u,d,p,v,b,y){return{value:i,root:s,parent:u,type:d,props:p,children:v,line:HX,column:xD,length:b,return:"",siblings:y}}function $Rt(){return I0}function zRt(){return I0=Nv>0?eR(kD,--Nv):0,xD--,I0===10&&(xD=1,HX--),I0}function B3(){return I0=Nv2||_2e(I0)>3?"":" "}function URt(i,s){for(;--s&&B3()&&!(I0<48||I0>102||I0>57&&I0<65||I0>70&&I0<97););return UX(i,VX()+(s<6&&PC()==32&&B3()==32))}function L2e(i){for(;B3();)switch(I0){case i:return Nv;case 34:case 39:i!==34&&i!==39&&L2e(I0);break;case 40:i===41&&L2e(i);break;case 92:B3();break}return Nv}function GRt(i,s){for(;B3()&&i+I0!==47+10;)if(i+I0===42+42&&PC()===47)break;return"/*"+UX(s,Nv-1)+"*"+C2e(i===47?i:B3())}function KRt(i){for(;!_2e(PC());)B3();return UX(i,Nv)}function WRt(i){return HRt(GX("",null,null,null,[""],i=qRt(i),0,[0],i))}function GX(i,s,u,d,p,v,b,y,T){for(var _=0,A=0,P=b,R=0,F=0,j=0,K=1,ee=1,ie=1,oe=0,pe="",be=p,ae=v,ne=d,se=pe;ee;)switch(j=oe,oe=B3()){case 40:if(j!=108&&eR(se,P-1)==58){RRt(se+=zX(A2e(oe),"&","&\f"),"&\f",Eje(_?y[_-1]:0))!=-1&&(ie=-1);break}case 34:case 39:case 91:se+=A2e(oe);break;case 9:case 10:case 13:case 32:se+=VRt(j);break;case 92:se+=URt(VX()-1,7);continue;case 47:switch(PC()){case 42:case 47:qX(YRt(GRt(B3(),VX()),s,u,T),T);break;default:se+="/"}break;case 123*K:y[_++]=_7(se)*ie;case 125*K:case 59:case 0:switch(oe){case 0:case 125:ee=0;case 59+A:ie==-1&&(se=zX(se,/\f/g,"")),F>0&&_7(se)-P&&qX(F>32?_je(se+";",d,u,P-1,T):_je(zX(se," ","")+";",d,u,P-2,T),T);break;case 59:se+=";";default:if(qX(ne=Sje(se,s,u,_,A,p,y,pe,be=[],ae=[],P,v),v),oe===123)if(A===0)GX(se,s,ne,ne,be,v,P,y,ae);else switch(R===99&&eR(se,3)===110?100:R){case 100:case 108:case 109:case 115:GX(i,ne,ne,d&&qX(Sje(i,ne,ne,0,0,p,y,pe,p,be=[],P,ae),ae),p,ae,P,y,d?be:ae);break;default:GX(se,ne,ne,ne,[""],ae,0,y,ae)}}_=A=F=0,K=ie=1,pe=se="",P=b;break;case 58:P=1+_7(se),F=j;default:if(K<1){if(oe==123)--K;else if(oe==125&&K++==0&&zRt()==125)continue}switch(se+=C2e(oe),oe*K){case 38:ie=A>0?1:(se+="\f",-1);break;case 44:y[_++]=(_7(se)-1)*ie,ie=1;break;case 64:PC()===45&&(se+=A2e(B3())),R=PC(),A=P=_7(pe=se+=KRt(VX())),oe++;break;case 45:j===45&&_7(se)==2&&(K=0)}}return v}function Sje(i,s,u,d,p,v,b,y,T,_,A,P){for(var R=p-1,F=p===0?v:[""],j=jRt(F),K=0,ee=0,ie=0;K0?F[oe]+" "+pe:zX(pe,/&\f/g,F[oe])))&&(T[ie++]=be);return S2e(i,s,u,p===0?xje:y,T,_,A,P)}function YRt(i,s,u,d){return S2e(i,s,u,yje,C2e($Rt()),tR(i,2,-2),0,d)}function _je(i,s,u,d,p){return S2e(i,s,u,kje,tR(i,0,d),tR(i,d+1,-1),d,p)}function M2e(i,s){for(var u="",d=0;d{let u=id({},i),d={};for(const p of s)Ije(p),d=id(d,p);if(u=id(u,d),d.theme&&d.theme in E7){const p=id({},Lje),v=id(p.themeVariables||{},d.themeVariables);u.theme&&u.theme in E7&&(u.themeVariables=E7[u.theme].getThemeVariables(v))}return nR=u,Nje(nR),nR},QRt=i=>(B2=id({},ED),B2=id(B2,i),i.theme&&E7[i.theme]&&(B2.themeVariables=E7[i.theme].getThemeVariables(i.themeVariables)),KX(B2,TD),B2),JRt=i=>{Lje=id({},i)},ZRt=i=>(B2=id(B2,i),KX(B2,TD),B2),Mje=()=>id({},B2),Dje=i=>(Nje(i),id(nR,i),Vh()),Vh=()=>id({},nR),Ije=i=>{i&&(["secure",...B2.secure??[]].forEach(s=>{Object.hasOwn(i,s)&&(Xe.debug(`Denied attempt to modify a secure key ${s}`,i[s]),delete i[s])}),Object.keys(i).forEach(s=>{s.startsWith("__")&&delete i[s]}),Object.keys(i).forEach(s=>{typeof i[s]=="string"&&(i[s].includes("<")||i[s].includes(">")||i[s].includes("url(data:"))&&delete i[s],typeof i[s]=="object"&&Ije(i[s])}))},ejt=i=>{SX(i),i.fontFamily&&(!i.themeVariables||!i.themeVariables.fontFamily)&&(i.themeVariables={fontFamily:i.fontFamily}),TD.push(i),KX(B2,TD)},WX=(i=B2)=>{TD=[],KX(i,TD)},tjt={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},Oje={},njt=i=>{Oje[i]||(Xe.warn(tjt[i]),Oje[i]=!0)},Nje=i=>{i&&(i.lazyLoadedDiagrams||i.loadExternalDiagramsAtStartup)&&njt("LAZY_LOAD_DEPRECATED")},Pje="c4",rjt={id:Pje,detector:i=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>wUt);return{id:Pje,diagram:i}}},Bje="flowchart",ijt={id:Bje,detector:(i,s)=>{var u,d;return((u=s==null?void 0:s.flowchart)==null?void 0:u.defaultRenderer)==="dagre-wrapper"||((d=s==null?void 0:s.flowchart)==null?void 0:d.defaultRenderer)==="elk"?!1:/^\s*graph/.test(i)},loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>_en);return{id:Bje,diagram:i}}},Fje="flowchart-v2",sjt={id:Fje,detector:(i,s)=>{var u,d,p;return((u=s==null?void 0:s.flowchart)==null?void 0:u.defaultRenderer)==="dagre-d3"||((d=s==null?void 0:s.flowchart)==null?void 0:d.defaultRenderer)==="elk"?!1:/^\s*graph/.test(i)&&((p=s==null?void 0:s.flowchart)==null?void 0:p.defaultRenderer)==="dagre-wrapper"?!0:/^\s*flowchart/.test(i)},loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Aen);return{id:Fje,diagram:i}}},Rje="er",ajt={id:Rje,detector:i=>/^\s*erDiagram/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>etn);return{id:Rje,diagram:i}}},jje="gitGraph",ojt={id:jje,detector:i=>/^\s*gitGraph/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Stn);return{id:jje,diagram:i}}},$je="gantt",cjt={id:$je,detector:i=>/^\s*gantt/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>pnn);return{id:$je,diagram:i}}},zje="info",ujt={id:zje,detector:i=>/^\s*info/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>mnn);return{id:zje,diagram:i}}},qje="pie",ljt={id:qje,detector:i=>/^\s*pie/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Enn);return{id:qje,diagram:i}}},Hje="quadrantChart",hjt={id:Hje,detector:i=>/^\s*quadrantChart/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>jnn);return{id:Hje,diagram:i}}},Vje="xychart",fjt={id:Vje,detector:i=>/^\s*xychart-beta/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>urn);return{id:Vje,diagram:i}}},Uje="requirement",djt={id:Uje,detector:i=>/^\s*requirement(Diagram)?/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>wrn);return{id:Uje,diagram:i}}},Gje="sequence",gjt={id:Gje,detector:i=>/^\s*sequenceDiagram/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>kin);return{id:Gje,diagram:i}}},Kje="class",pjt={id:Kje,detector:(i,s)=>{var u;return((u=s==null?void 0:s.class)==null?void 0:u.defaultRenderer)==="dagre-wrapper"?!1:/^\s*classDiagram/.test(i)},loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Gin);return{id:Kje,diagram:i}}},Wje="classDiagram",bjt={id:Wje,detector:(i,s)=>{var u;return/^\s*classDiagram/.test(i)&&((u=s==null?void 0:s.class)==null?void 0:u.defaultRenderer)==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(i)},loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Jin);return{id:Wje,diagram:i}}},Yje="state",mjt={id:Yje,detector:(i,s)=>{var u;return((u=s==null?void 0:s.state)==null?void 0:u.defaultRenderer)==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(i)},loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>jsn);return{id:Yje,diagram:i}}},Xje="stateDiagram",vjt={id:Xje,detector:(i,s)=>{var u;return!!(/^\s*stateDiagram-v2/.test(i)||/^\s*stateDiagram/.test(i)&&((u=s==null?void 0:s.state)==null?void 0:u.defaultRenderer)==="dagre-wrapper")},loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>ian);return{id:Xje,diagram:i}}},Qje="journey",wjt={id:Qje,detector:i=>/^\s*journey/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Ean);return{id:Qje,diagram:i}}},yjt=function(i,s){for(let u of s)i.attr(u[0],u[1])},xjt=function(i,s,u){let d=new Map;return u?(d.set("width","100%"),d.set("style",`max-width: ${s}px;`)):(d.set("height",i),d.set("width",s)),d},Ng=function(i,s,u,d){const p=xjt(s,u,d);yjt(i,p)},y9=function(i,s,u,d){const p=s.node().getBBox(),v=p.width,b=p.height;Xe.info(`SVG bounds: ${v}x${b}`,p);let y=0,T=0;Xe.info(`Graph bounds: ${y}x${T}`,i),y=v+u*2,T=b+u*2,Xe.info(`Calculated bounds: ${y}x${T}`),Ng(s,T,y,d);const _=`${p.x-u} ${p.y-u} ${p.width+2*u} ${p.height+2*u}`;s.attr("viewBox",_)},YX={},kjt=(i,s,u)=>{let d="";return i in YX&&YX[i]?d=YX[i](u):Xe.warn(`No theme found for ${i}`),` & { + font-family: ${u.fontFamily}; + font-size: ${u.fontSize}; + fill: ${u.textColor} + } + + /* Classes common for multiple diagrams */ + + & .error-icon { + fill: ${u.errorBkgColor}; + } + & .error-text { + fill: ${u.errorTextColor}; + stroke: ${u.errorTextColor}; + } + + & .edge-thickness-normal { + stroke-width: 2px; + } + & .edge-thickness-thick { + stroke-width: 3.5px + } + & .edge-pattern-solid { + stroke-dasharray: 0; + } + + & .edge-pattern-dashed{ + stroke-dasharray: 3; + } + .edge-pattern-dotted { + stroke-dasharray: 2; + } + + & .marker { + fill: ${u.lineColor}; + stroke: ${u.lineColor}; + } + & .marker.cross { + stroke: ${u.lineColor}; + } + + & svg { + font-family: ${u.fontFamily}; + font-size: ${u.fontSize}; + } + + ${d} + + ${s} +`},Ejt=(i,s)=>{s!==void 0&&(YX[i]=s)},Tjt=kjt;let D2e="",I2e="",O2e="";const N2e=i=>Yf(i,Vh()),Pg=()=>{D2e="",O2e="",I2e=""},Bg=i=>{D2e=N2e(i).replace(/^\s+/g,"")},Cp=()=>D2e,Sp=i=>{O2e=N2e(i).replace(/\n\s+/g,` +`)},_p=()=>O2e,cm=i=>{I2e=N2e(i)},Ap=()=>I2e,Jje=Object.freeze(Object.defineProperty({__proto__:null,clear:Pg,getAccDescription:_p,getAccTitle:Cp,getDiagramTitle:Ap,setAccDescription:Sp,setAccTitle:Bg,setDiagramTitle:cm},Symbol.toStringTag,{value:"Module"})),Cjt=Xe,Sjt=fpe,qt=Vh,_jt=Dje,Zje=ED,Ajt=i=>Yf(i,qt()),e$e=y9,Ljt=()=>Jje,XX={},QX=(i,s,u)=>{var d;if(XX[i])throw new Error(`Diagram ${i} already registered.`);XX[i]=s,u&&PRe(i,u),Ejt(i,s.styles),(d=s.injectUtils)==null||d.call(s,Cjt,Sjt,qt,Ajt,e$e,Ljt(),()=>{})},P2e=i=>{if(i in XX)return XX[i];throw new Mjt(i)};class Mjt extends Error{constructor(s){super(`Diagram ${s} not found.`)}}const rR=i=>{var p;const{securityLevel:s}=qt();let u=Ir("body");if(s==="sandbox"){const b=((p=Ir(`#i${i}`).node())==null?void 0:p.contentDocument)??document;u=Ir(b.body)}return u.select(`#${i}`)},t$e={draw:(i,s,u)=>{Xe.debug(`rendering svg for syntax error +`);const d=rR(s),p=d.append("g");d.attr("viewBox","0 0 2412 512"),Ng(d,100,512,!0),p.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"),p.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"),p.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"),p.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"),p.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"),p.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"),p.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"),p.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${u}`)}},Djt=t$e,Ijt={db:{},renderer:t$e,parser:{parser:{yy:{}},parse:()=>{}}},n$e="flowchart-elk",Ojt={id:n$e,detector:(i,s)=>{var u;return!!(/^\s*flowchart-elk/.test(i)||/^\s*flowchart|graph/.test(i)&&((u=s==null?void 0:s.flowchart)==null?void 0:u.defaultRenderer)==="elk")},loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>jan);return{id:n$e,diagram:i}}},r$e="timeline",Njt={id:r$e,detector:i=>/^\s*timeline/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>ion);return{id:r$e,diagram:i}}},i$e="mindmap",Pjt={id:i$e,detector:i=>/^\s*mindmap/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Ion);return{id:i$e,diagram:i}}},s$e="sankey",Bjt={id:s$e,detector:i=>/^\s*sankey-beta/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>ccn);return{id:s$e,diagram:i}}},a$e="block",Fjt={id:a$e,detector:i=>/^\s*block-beta/.test(i),loader:async()=>{const{diagram:i}=await Promise.resolve().then(()=>Mcn);return{id:a$e,diagram:i}}};let o$e=!1;const B2e=()=>{o$e||(o$e=!0,QX("error",Ijt,i=>i.toLowerCase().trim()==="error"),QX("---",{db:{clear:()=>{}},styles:{},renderer:{draw:()=>{}},parser:{parser:{yy:{}},parse:()=>{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")}},init:()=>null},i=>i.toLowerCase().trimStart().startsWith("---")),NRe(rjt,bjt,pjt,ajt,cjt,ujt,ljt,djt,gjt,Ojt,sjt,ijt,Pjt,Njt,ojt,vjt,mjt,wjt,hjt,Bjt,fjt,Fjt))};class c$e{constructor(s,u={}){this.text=s,this.metadata=u,this.type="graph",this.text=NRt(s),this.text+=` +`;const d=Vh();try{this.type=_X(s,d)}catch(v){this.type="error",this.detectError=v}const p=P2e(this.type);Xe.debug("Type "+this.type),this.db=p.db,this.renderer=p.renderer,this.parser=p.parser,this.parser.parser.yy=this.db,this.init=p.init,this.parse()}parse(){var u,d,p,v,b;if(this.detectError)throw this.detectError;(d=(u=this.db).clear)==null||d.call(u);const s=Vh();(p=this.init)==null||p.call(this,s),this.metadata.title&&((b=(v=this.db).setDiagramTitle)==null||b.call(v,this.metadata.title)),this.parser.parse(this.text)}async render(s,u){await this.renderer.draw(this.text,s,u,this)}getParser(){return this.parser}getType(){return this.type}}const Rjt=async(i,s={})=>{const u=_X(i,Vh());try{P2e(u)}catch{const p=$Pt(u);if(!p)throw new ORe(`Diagram ${u} not found.`);const{id:v,diagram:b}=await p();QX(v,b)}return new c$e(i,s)};let u$e=[];const jjt=()=>{u$e.forEach(i=>{i()}),u$e=[]};var $jt=WRe(Object.keys,Object);const zjt=$jt;var qjt=Object.prototype,Hjt=qjt.hasOwnProperty;function l$e(i){if(!OX(i))return zjt(i);var s=[];for(var u in Object(i))Hjt.call(i,u)&&u!="constructor"&&s.push(u);return s}var Vjt=MC(N3,"DataView");const F2e=Vjt;var Ujt=MC(N3,"Promise");const R2e=Ujt;var Gjt=MC(N3,"Set");const CD=Gjt;var Kjt=MC(N3,"WeakMap");const j2e=Kjt;var h$e="[object Map]",Wjt="[object Object]",f$e="[object Promise]",d$e="[object Set]",g$e="[object WeakMap]",p$e="[object DataView]",Yjt=LC(F2e),Xjt=LC(WF),Qjt=LC(R2e),Jjt=LC(CD),Zjt=LC(j2e),BC=AC;(F2e&&BC(new F2e(new ArrayBuffer(1)))!=p$e||WF&&BC(new WF)!=h$e||R2e&&BC(R2e.resolve())!=f$e||CD&&BC(new CD)!=d$e||j2e&&BC(new j2e)!=g$e)&&(BC=function(i){var s=AC(i),u=s==Wjt?i.constructor:void 0,d=u?LC(u):"";if(d)switch(d){case Yjt:return p$e;case Xjt:return h$e;case Qjt:return f$e;case Jjt:return d$e;case Zjt:return g$e}return s});const SD=BC;var e$t="[object Map]",t$t="[object Set]",n$t=Object.prototype,r$t=n$t.hasOwnProperty;function iR(i){if(i==null)return!0;if(w9(i)&&(D0(i)||typeof i=="string"||typeof i.splice=="function"||vD(i)||PX(i)||mD(i)))return!i.length;var s=SD(i);if(s==e$t||s==t$t)return!i.size;if(OX(i))return!l$e(i).length;for(var u in i)if(r$t.call(i,u))return!1;return!0}const i$t="graphics-document document";function s$t(i,s){i.attr("role",i$t),s!==""&&i.attr("aria-roledescription",s)}function a$t(i,s,u,d){if(i.insert!==void 0){if(u){const p=`chart-desc-${d}`;i.attr("aria-describedby",p),i.insert("desc",":first-child").attr("id",p).text(u)}if(s){const p=`chart-title-${d}`;i.attr("aria-labelledby",p),i.insert("title",":first-child").attr("id",p).text(s)}}}const o$t=i=>i.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart();/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */function b$e(i){return typeof i>"u"||i===null}function c$t(i){return typeof i=="object"&&i!==null}function u$t(i){return Array.isArray(i)?i:b$e(i)?[]:[i]}function l$t(i,s){var u,d,p,v;if(s)for(v=Object.keys(s),u=0,d=v.length;uy&&(v=" ... ",s=d-y+v.length),u-d>y&&(b=" ...",u=d+y-b.length),{str:v+i.slice(s,u).replace(/\t/g,"→")+b,pos:d-s+v.length}}function z2e(i,s){return Lp.repeat(" ",s-i.length)+i}function w$t(i,s){if(s=Object.create(s||null),!i.buffer)return null;s.maxLength||(s.maxLength=79),typeof s.indent!="number"&&(s.indent=1),typeof s.linesBefore!="number"&&(s.linesBefore=3),typeof s.linesAfter!="number"&&(s.linesAfter=2);for(var u=/\r?\n|\r|\0/g,d=[0],p=[],v,b=-1;v=u.exec(i.buffer);)p.push(v.index),d.push(v.index+v[0].length),i.position<=v.index&&b<0&&(b=d.length-2);b<0&&(b=d.length-1);var y="",T,_,A=Math.min(i.line+s.linesAfter,p.length).toString().length,P=s.maxLength-(s.indent+A+3);for(T=1;T<=s.linesBefore&&!(b-T<0);T++)_=$2e(i.buffer,d[b-T],p[b-T],i.position-(d[b]-d[b-T]),P),y=Lp.repeat(" ",s.indent)+z2e((i.line-T+1).toString(),A)+" | "+_.str+` +`+y;for(_=$2e(i.buffer,d[b],p[b],i.position,P),y+=Lp.repeat(" ",s.indent)+z2e((i.line+1).toString(),A)+" | "+_.str+` +`,y+=Lp.repeat("-",s.indent+A+3+_.pos)+`^ +`,T=1;T<=s.linesAfter&&!(b+T>=p.length);T++)_=$2e(i.buffer,d[b+T],p[b+T],i.position-(d[b]-d[b+T]),P),y+=Lp.repeat(" ",s.indent)+z2e((i.line+T+1).toString(),A)+" | "+_.str+` +`;return y.replace(/\n$/,"")}var y$t=w$t,x$t=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],k$t=["scalar","sequence","mapping"];function E$t(i){var s={};return i!==null&&Object.keys(i).forEach(function(u){i[u].forEach(function(d){s[String(d)]=u})}),s}function T$t(i,s){if(s=s||{},Object.keys(s).forEach(function(u){if(x$t.indexOf(u)===-1)throw new A7('Unknown option "'+u+'" is met in definition of "'+i+'" YAML type.')}),this.options=s,this.tag=i,this.kind=s.kind||null,this.resolve=s.resolve||function(){return!0},this.construct=s.construct||function(u){return u},this.instanceOf=s.instanceOf||null,this.predicate=s.predicate||null,this.represent=s.represent||null,this.representName=s.representName||null,this.defaultStyle=s.defaultStyle||null,this.multi=s.multi||!1,this.styleAliases=E$t(s.styleAliases||null),k$t.indexOf(this.kind)===-1)throw new A7('Unknown kind "'+this.kind+'" is specified for "'+i+'" YAML type.')}var Fg=T$t;function v$e(i,s){var u=[];return i[s].forEach(function(d){var p=u.length;u.forEach(function(v,b){v.tag===d.tag&&v.kind===d.kind&&v.multi===d.multi&&(p=b)}),u[p]=d}),u}function C$t(){var i={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}},s,u;function d(p){p.multi?(i.multi[p.kind].push(p),i.multi.fallback.push(p)):i[p.kind][p.tag]=i.fallback[p.tag]=p}for(s=0,u=arguments.length;s=0?"0b"+i.toString(2):"-0b"+i.toString(2).slice(1)},octal:function(i){return i>=0?"0o"+i.toString(8):"-0o"+i.toString(8).slice(1)},decimal:function(i){return i.toString(10)},hexadecimal:function(i){return i>=0?"0x"+i.toString(16).toUpperCase():"-0x"+i.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),G$t=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function K$t(i){return!(i===null||!G$t.test(i)||i[i.length-1]==="_")}function W$t(i){var s,u;return s=i.replace(/_/g,"").toLowerCase(),u=s[0]==="-"?-1:1,"+-".indexOf(s[0])>=0&&(s=s.slice(1)),s===".inf"?u===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:s===".nan"?NaN:u*parseFloat(s,10)}var Y$t=/^[-+]?[0-9]+e/;function X$t(i,s){var u;if(isNaN(i))switch(s){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===i)switch(s){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===i)switch(s){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(Lp.isNegativeZero(i))return"-0.0";return u=i.toString(10),Y$t.test(u)?u.replace("e",".e"):u}function Q$t(i){return Object.prototype.toString.call(i)==="[object Number]"&&(i%1!==0||Lp.isNegativeZero(i))}var J$t=new Fg("tag:yaml.org,2002:float",{kind:"scalar",resolve:K$t,construct:W$t,predicate:Q$t,represent:X$t,defaultStyle:"lowercase"}),w$e=M$t.extend({implicit:[N$t,R$t,U$t,J$t]}),Z$t=w$e,y$e=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),x$e=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]))?))?$");function ezt(i){return i===null?!1:y$e.exec(i)!==null||x$e.exec(i)!==null}function tzt(i){var s,u,d,p,v,b,y,T=0,_=null,A,P,R;if(s=y$e.exec(i),s===null&&(s=x$e.exec(i)),s===null)throw new Error("Date resolve error");if(u=+s[1],d=+s[2]-1,p=+s[3],!s[4])return new Date(Date.UTC(u,d,p));if(v=+s[4],b=+s[5],y=+s[6],s[7]){for(T=s[7].slice(0,3);T.length<3;)T+="0";T=+T}return s[9]&&(A=+s[10],P=+(s[11]||0),_=(A*60+P)*6e4,s[9]==="-"&&(_=-_)),R=new Date(Date.UTC(u,d,p,v,b,y,T)),_&&R.setTime(R.getTime()-_),R}function nzt(i){return i.toISOString()}var rzt=new Fg("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:ezt,construct:tzt,instanceOf:Date,represent:nzt});function izt(i){return i==="<<"||i===null}var szt=new Fg("tag:yaml.org,2002:merge",{kind:"scalar",resolve:izt}),H2e=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function azt(i){if(i===null)return!1;var s,u,d=0,p=i.length,v=H2e;for(u=0;u64)){if(s<0)return!1;d+=6}return d%8===0}function ozt(i){var s,u,d=i.replace(/[\r\n=]/g,""),p=d.length,v=H2e,b=0,y=[];for(s=0;s>16&255),y.push(b>>8&255),y.push(b&255)),b=b<<6|v.indexOf(d.charAt(s));return u=p%4*6,u===0?(y.push(b>>16&255),y.push(b>>8&255),y.push(b&255)):u===18?(y.push(b>>10&255),y.push(b>>2&255)):u===12&&y.push(b>>4&255),new Uint8Array(y)}function czt(i){var s="",u=0,d,p,v=i.length,b=H2e;for(d=0;d>18&63],s+=b[u>>12&63],s+=b[u>>6&63],s+=b[u&63]),u=(u<<8)+i[d];return p=v%3,p===0?(s+=b[u>>18&63],s+=b[u>>12&63],s+=b[u>>6&63],s+=b[u&63]):p===2?(s+=b[u>>10&63],s+=b[u>>4&63],s+=b[u<<2&63],s+=b[64]):p===1&&(s+=b[u>>2&63],s+=b[u<<4&63],s+=b[64],s+=b[64]),s}function uzt(i){return Object.prototype.toString.call(i)==="[object Uint8Array]"}var lzt=new Fg("tag:yaml.org,2002:binary",{kind:"scalar",resolve:azt,construct:ozt,predicate:uzt,represent:czt}),hzt=Object.prototype.hasOwnProperty,fzt=Object.prototype.toString;function dzt(i){if(i===null)return!0;var s=[],u,d,p,v,b,y=i;for(u=0,d=y.length;u>10)+55296,(i-65536&1023)+56320)}for(var L$e=new Array(256),M$e=new Array(256),AD=0;AD<256;AD++)L$e[AD]=A$e(AD)?1:0,M$e[AD]=A$e(AD);function Ozt(i,s){this.input=i,this.filename=s.filename||null,this.schema=s.schema||Tzt,this.onWarning=s.onWarning||null,this.legacy=s.legacy||!1,this.json=s.json||!1,this.listener=s.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=i.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function D$e(i,s){var u={name:i.filename,buffer:i.input.slice(0,-1),position:i.position,line:i.line,column:i.position-i.lineStart};return u.snippet=y$t(u),new A7(s,u)}function oa(i,s){throw D$e(i,s)}function eQ(i,s){i.onWarning&&i.onWarning.call(null,D$e(i,s))}var I$e={YAML:function(s,u,d){var p,v,b;s.version!==null&&oa(s,"duplication of %YAML directive"),d.length!==1&&oa(s,"YAML directive accepts exactly one argument"),p=/^([0-9]+)\.([0-9]+)$/.exec(d[0]),p===null&&oa(s,"ill-formed argument of the YAML directive"),v=parseInt(p[1],10),b=parseInt(p[2],10),v!==1&&oa(s,"unacceptable YAML version of the document"),s.version=d[0],s.checkLineBreaks=b<2,b!==1&&b!==2&&eQ(s,"unsupported YAML version of the document")},TAG:function(s,u,d){var p,v;d.length!==2&&oa(s,"TAG directive accepts exactly two arguments"),p=d[0],v=d[1],C$e.test(p)||oa(s,"ill-formed tag handle (first argument) of the TAG directive"),x9.call(s.tagMap,p)&&oa(s,'there is a previously declared suffix for "'+p+'" tag handle'),S$e.test(v)||oa(s,"ill-formed tag prefix (second argument) of the TAG directive");try{v=decodeURIComponent(v)}catch{oa(s,"tag prefix is malformed: "+v)}s.tagMap[p]=v}};function k9(i,s,u,d){var p,v,b,y;if(s1&&(i.result+=Lp.repeat(` +`,s-1))}function Nzt(i,s,u){var d,p,v,b,y,T,_,A,P=i.kind,R=i.result,F;if(F=i.input.charCodeAt(i.position),F2(F)||_D(F)||F===35||F===38||F===42||F===33||F===124||F===62||F===39||F===34||F===37||F===64||F===96||(F===63||F===45)&&(p=i.input.charCodeAt(i.position+1),F2(p)||u&&_D(p)))return!1;for(i.kind="scalar",i.result="",v=b=i.position,y=!1;F!==0;){if(F===58){if(p=i.input.charCodeAt(i.position+1),F2(p)||u&&_D(p))break}else if(F===35){if(d=i.input.charCodeAt(i.position-1),F2(d))break}else{if(i.position===i.lineStart&&tQ(i)||u&&_D(F))break;if(V4(F))if(T=i.line,_=i.lineStart,A=i.lineIndent,O0(i,!1,-1),i.lineIndent>=s){y=!0,F=i.input.charCodeAt(i.position);continue}else{i.position=b,i.line=T,i.lineStart=_,i.lineIndent=A;break}}y&&(k9(i,v,b,!1),G2e(i,i.line-T),v=b=i.position,y=!1),FC(F)||(b=i.position+1),F=i.input.charCodeAt(++i.position)}return k9(i,v,b,!1),i.result?!0:(i.kind=P,i.result=R,!1)}function Pzt(i,s){var u,d,p;if(u=i.input.charCodeAt(i.position),u!==39)return!1;for(i.kind="scalar",i.result="",i.position++,d=p=i.position;(u=i.input.charCodeAt(i.position))!==0;)if(u===39)if(k9(i,d,i.position,!0),u=i.input.charCodeAt(++i.position),u===39)d=i.position,i.position++,p=i.position;else return!0;else V4(u)?(k9(i,d,p,!0),G2e(i,O0(i,!1,s)),d=p=i.position):i.position===i.lineStart&&tQ(i)?oa(i,"unexpected end of the document within a single quoted scalar"):(i.position++,p=i.position);oa(i,"unexpected end of the stream within a single quoted scalar")}function Bzt(i,s){var u,d,p,v,b,y;if(y=i.input.charCodeAt(i.position),y!==34)return!1;for(i.kind="scalar",i.result="",i.position++,u=d=i.position;(y=i.input.charCodeAt(i.position))!==0;){if(y===34)return k9(i,u,i.position,!0),i.position++,!0;if(y===92){if(k9(i,u,i.position,!0),y=i.input.charCodeAt(++i.position),V4(y))O0(i,!1,s);else if(y<256&&L$e[y])i.result+=M$e[y],i.position++;else if((b=Mzt(y))>0){for(p=b,v=0;p>0;p--)y=i.input.charCodeAt(++i.position),(b=Lzt(y))>=0?v=(v<<4)+b:oa(i,"expected hexadecimal character");i.result+=Izt(v),i.position++}else oa(i,"unknown escape sequence");u=d=i.position}else V4(y)?(k9(i,u,d,!0),G2e(i,O0(i,!1,s)),u=d=i.position):i.position===i.lineStart&&tQ(i)?oa(i,"unexpected end of the document within a double quoted scalar"):(i.position++,d=i.position)}oa(i,"unexpected end of the stream within a double quoted scalar")}function Fzt(i,s){var u=!0,d,p,v,b=i.tag,y,T=i.anchor,_,A,P,R,F,j=Object.create(null),K,ee,ie,oe;if(oe=i.input.charCodeAt(i.position),oe===91)A=93,F=!1,y=[];else if(oe===123)A=125,F=!0,y={};else return!1;for(i.anchor!==null&&(i.anchorMap[i.anchor]=y),oe=i.input.charCodeAt(++i.position);oe!==0;){if(O0(i,!0,s),oe=i.input.charCodeAt(i.position),oe===A)return i.position++,i.tag=b,i.anchor=T,i.kind=F?"mapping":"sequence",i.result=y,!0;u?oe===44&&oa(i,"expected the node content, but found ','"):oa(i,"missed comma between flow collection entries"),ee=K=ie=null,P=R=!1,oe===63&&(_=i.input.charCodeAt(i.position+1),F2(_)&&(P=R=!0,i.position++,O0(i,!0,s))),d=i.line,p=i.lineStart,v=i.position,MD(i,s,JX,!1,!0),ee=i.tag,K=i.result,O0(i,!0,s),oe=i.input.charCodeAt(i.position),(R||i.line===d)&&oe===58&&(P=!0,oe=i.input.charCodeAt(++i.position),O0(i,!0,s),MD(i,s,JX,!1,!0),ie=i.result),F?LD(i,y,j,ee,K,ie,d,p,v):P?y.push(LD(i,null,j,ee,K,ie,d,p,v)):y.push(K),O0(i,!0,s),oe=i.input.charCodeAt(i.position),oe===44?(u=!0,oe=i.input.charCodeAt(++i.position)):u=!1}oa(i,"unexpected end of the stream within a flow collection")}function Rzt(i,s){var u,d,p=V2e,v=!1,b=!1,y=s,T=0,_=!1,A,P;if(P=i.input.charCodeAt(i.position),P===124)d=!1;else if(P===62)d=!0;else return!1;for(i.kind="scalar",i.result="";P!==0;)if(P=i.input.charCodeAt(++i.position),P===43||P===45)V2e===p?p=P===43?T$e:Czt:oa(i,"repeat of a chomping mode identifier");else if((A=Dzt(P))>=0)A===0?oa(i,"bad explicit indentation width of a block scalar; it cannot be less than one"):b?oa(i,"repeat of an indentation width identifier"):(y=s+A-1,b=!0);else break;if(FC(P)){do P=i.input.charCodeAt(++i.position);while(FC(P));if(P===35)do P=i.input.charCodeAt(++i.position);while(!V4(P)&&P!==0)}for(;P!==0;){for(U2e(i),i.lineIndent=0,P=i.input.charCodeAt(i.position);(!b||i.lineIndenty&&(y=i.lineIndent),V4(P)){T++;continue}if(i.lineIndents)&&T!==0)oa(i,"bad indentation of a sequence entry");else if(i.lineIndents)&&(ee&&(b=i.line,y=i.lineStart,T=i.position),MD(i,s,ZX,!0,p)&&(ee?j=i.result:K=i.result),ee||(LD(i,P,R,F,j,K,b,y,T),F=j=K=null),O0(i,!0,-1),oe=i.input.charCodeAt(i.position)),(i.line===v||i.lineIndent>s)&&oe!==0)oa(i,"bad indentation of a mapping entry");else if(i.lineIndents?T=1:i.lineIndent===s?T=0:i.lineIndents?T=1:i.lineIndent===s?T=0:i.lineIndent tag; it should be "scalar", not "'+i.kind+'"'),P=0,R=i.implicitTypes.length;P"),i.result!==null&&j.kind!==i.kind&&oa(i,"unacceptable node kind for !<"+i.tag+'> tag; it should be "'+j.kind+'", not "'+i.kind+'"'),j.resolve(i.result,i.tag)?(i.result=j.construct(i.result,i.tag),i.anchor!==null&&(i.anchorMap[i.anchor]=i.result)):oa(i,"cannot resolve a node with !<"+i.tag+"> explicit tag")}return i.listener!==null&&i.listener("close",i),i.tag!==null||i.anchor!==null||A}function Hzt(i){var s=i.position,u,d,p,v=!1,b;for(i.version=null,i.checkLineBreaks=i.legacy,i.tagMap=Object.create(null),i.anchorMap=Object.create(null);(b=i.input.charCodeAt(i.position))!==0&&(O0(i,!0,-1),b=i.input.charCodeAt(i.position),!(i.lineIndent>0||b!==37));){for(v=!0,b=i.input.charCodeAt(++i.position),u=i.position;b!==0&&!F2(b);)b=i.input.charCodeAt(++i.position);for(d=i.input.slice(u,i.position),p=[],d.length<1&&oa(i,"directive name must not be less than one character in length");b!==0;){for(;FC(b);)b=i.input.charCodeAt(++i.position);if(b===35){do b=i.input.charCodeAt(++i.position);while(b!==0&&!V4(b));break}if(V4(b))break;for(u=i.position;b!==0&&!F2(b);)b=i.input.charCodeAt(++i.position);p.push(i.input.slice(u,i.position))}b!==0&&U2e(i),x9.call(I$e,d)?I$e[d](i,d,p):eQ(i,'unknown document directive "'+d+'"')}if(O0(i,!0,-1),i.lineIndent===0&&i.input.charCodeAt(i.position)===45&&i.input.charCodeAt(i.position+1)===45&&i.input.charCodeAt(i.position+2)===45?(i.position+=3,O0(i,!0,-1)):v&&oa(i,"directives end mark is expected"),MD(i,i.lineIndent-1,ZX,!1,!0),O0(i,!0,-1),i.checkLineBreaks&&_zt.test(i.input.slice(s,i.position))&&eQ(i,"non-ASCII line breaks are interpreted as content"),i.documents.push(i.result),i.position===i.lineStart&&tQ(i)){i.input.charCodeAt(i.position)===46&&(i.position+=3,O0(i,!0,-1));return}if(i.position"u"&&(u=s,s=null);var d=P$e(i,u);if(typeof s!="function")return d;for(var p=0,v=d.length;pi.replace(/\r\n?/g,` +`).replace(/<(\w+)([^>]*)>/g,(s,u,d)=>"<"+u+d.replace(/="([^"]*)"/g,"='$1'")+">"),Zzt=i=>{const{text:s,metadata:u}=Qzt(i),{displayMode:d,title:p,config:v={}}=u;return d&&(v.gantt||(v.gantt={}),v.gantt.displayMode=d),{title:p,config:v,text:s}},eqt=i=>{const s=Ao.detectInit(i)??{},u=Ao.detectDirective(i,"wrap");return Array.isArray(u)?s.wrap=u.some(({type:d})=>{}):(u==null?void 0:u.type)==="wrap"&&(s.wrap=!0),{text:wRt(i),directive:s}};function B$e(i){const s=Jzt(i),u=Zzt(s),d=eqt(u.text),p=JF(u.config,d.directive);return i=o$t(d.text),{code:i,title:u.title,config:p}}const tqt=5e4,nqt="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa",rqt="sandbox",iqt="loose",sqt="http://www.w3.org/2000/svg",aqt="http://www.w3.org/1999/xlink",oqt="http://www.w3.org/1999/xhtml",cqt="100%",uqt="100%",lqt="border:0;margin:0;",hqt="margin:0",fqt="allow-top-navigation-by-user-activation allow-popups",dqt='The "iframe" tag is not supported by your browser.',gqt=["foreignobject"],pqt=["dominant-baseline"];function F$e(i){const s=B$e(i);return WX(),ejt(s.config??{}),s}async function bqt(i,s){B2e(),i=F$e(i).code;try{await K2e(i)}catch(u){if(s!=null&&s.suppressErrors)return!1;throw u}return!0}const R$e=(i,s,u=[])=>` +.${i} ${s} { ${u.join(" !important; ")} !important; }`,mqt=(i,s={})=>{var d;let u="";if(i.themeCSS!==void 0&&(u+=` +${i.themeCSS}`),i.fontFamily!==void 0&&(u+=` +:root { --mermaid-font-family: ${i.fontFamily}}`),i.altFontFamily!==void 0&&(u+=` +:root { --mermaid-alt-font-family: ${i.altFontFamily}}`),!iR(s)){const y=i.htmlLabels||((d=i.flowchart)==null?void 0:d.htmlLabels)?["> *","span"]:["rect","polygon","ellipse","circle","path"];for(const T in s){const _=s[T];iR(_.styles)||y.forEach(A=>{u+=R$e(_.id,A,_.styles)}),iR(_.textStyles)||(u+=R$e(_.id,"tspan",_.textStyles))}}return u},vqt=(i,s,u,d)=>{const p=mqt(i,u),v=Tjt(s,p,i.themeVariables);return M2e(WRt(`${d}{${v}}`),XRt)},wqt=(i="",s,u)=>{let d=i;return!u&&!s&&(d=d.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),d=ZF(d),d=d.replace(/
/g,"
"),d},yqt=(i="",s)=>{var p,v;const u=(v=(p=s==null?void 0:s.viewBox)==null?void 0:p.baseVal)!=null&&v.height?s.viewBox.baseVal.height+"px":uqt,d=btoa(''+i+"");return``},j$e=(i,s,u,d,p)=>{const v=i.append("div");v.attr("id",u),d&&v.attr("style",d);const b=v.append("svg").attr("id",s).attr("width","100%").attr("xmlns",sqt);return p&&b.attr("xmlns:xlink",p),b.append("g"),i};function $$e(i,s){return i.append("iframe").attr("id",s).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const xqt=(i,s,u,d)=>{var p,v,b;(p=i.getElementById(s))==null||p.remove(),(v=i.getElementById(u))==null||v.remove(),(b=i.getElementById(d))==null||b.remove()},kqt=async function(i,s,u){var U,Fe,Pe,je,Ie,Se;B2e();const d=F$e(s);s=d.code;const p=Vh();Xe.debug(p),s.length>((p==null?void 0:p.maxTextSize)??tqt)&&(s=nqt);const v="#"+i,b="i"+i,y="#"+b,T="d"+i,_="#"+T;let A=Ir("body");const P=p.securityLevel===rqt,R=p.securityLevel===iqt,F=p.fontFamily;if(u!==void 0){if(u&&(u.innerHTML=""),P){const Ce=$$e(Ir(u),b);A=Ir(Ce.nodes()[0].contentDocument.body),A.node().style.margin=0}else A=Ir(u);j$e(A,i,T,`font-family: ${F}`,aqt)}else{if(xqt(document,i,T,b),P){const Ce=$$e(Ir("body"),b);A=Ir(Ce.nodes()[0].contentDocument.body),A.node().style.margin=0}else A=Ir("body");j$e(A,i,T)}let j,K;try{j=await K2e(s,{title:d.title})}catch(Ce){j=new c$e("error"),K=Ce}const ee=A.select(_).node(),ie=j.type,oe=ee.firstChild,pe=oe.firstChild,be=(Fe=(U=j.renderer).getClasses)==null?void 0:Fe.call(U,s,j),ae=vqt(p,ie,be,v),ne=document.createElement("style");ne.innerHTML=ae,oe.insertBefore(ne,pe);try{await j.renderer.draw(s,i,Aje,j)}catch(Ce){throw Djt.draw(s,i,Aje),Ce}const se=A.select(`${_} svg`),de=(je=(Pe=j.db).getAccTitle)==null?void 0:je.call(Pe),X=(Se=(Ie=j.db).getAccDescription)==null?void 0:Se.call(Ie);Tqt(ie,se,de,X),A.select(`[id="${i}"]`).selectAll("foreignobject > *").attr("xmlns",oqt);let ge=A.select(_).node().innerHTML;if(Xe.debug("config.arrowMarkerAbsolute",p.arrowMarkerAbsolute),ge=wqt(ge,P,f1(p.arrowMarkerAbsolute)),P){const Ce=A.select(_+" svg").node();ge=yqt(ge,Ce)}else R||(ge=hD.sanitize(ge,{ADD_TAGS:gqt,ADD_ATTR:pqt}));if(jjt(),K)throw K;const xe=Ir(P?y:_).node();return xe&&"remove"in xe&&xe.remove(),{svg:ge,bindFunctions:j.db.bindFunctions}};function Eqt(i={}){var u;i!=null&&i.fontFamily&&!((u=i.themeVariables)!=null&&u.fontFamily)&&(i.themeVariables||(i.themeVariables={}),i.themeVariables.fontFamily=i.fontFamily),JRt(i),i!=null&&i.theme&&i.theme in E7?i.themeVariables=E7[i.theme].getThemeVariables(i.themeVariables):i&&(i.themeVariables=E7.default.getThemeVariables(i.themeVariables));const s=typeof i=="object"?QRt(i):Mje();fpe(s.logLevel),B2e()}const K2e=(i,s={})=>{const{code:u}=B$e(i);return Rjt(u,s)};function Tqt(i,s,u,d){s$t(s,i),a$t(s,u,d,s.attr("id"))}const RC=Object.freeze({render:kqt,parse:bqt,getDiagramFromText:K2e,initialize:Eqt,getConfig:Vh,setConfig:Dje,getSiteConfig:Mje,updateSiteConfig:ZRt,reset:()=>{WX()},globalReset:()=>{WX(ED)},defaultConfig:ED});fpe(Vh().logLevel),WX(Vh());const Cqt=async()=>{Xe.debug("Loading registered diagrams");const s=(await Promise.allSettled(Object.entries(dD).map(async([u,{detector:d,loader:p}])=>{if(p)try{P2e(u)}catch{try{const{diagram:b,id:y}=await p();QX(y,b,d)}catch(b){throw Xe.error(`Failed to load external diagram with key ${u}. Removing from detectors.`),delete dD[u],b}}}))).filter(u=>u.status==="rejected");if(s.length>0){Xe.error(`Failed to load ${s.length} external diagrams`);for(const u of s)Xe.error(u);throw new Error(`Failed to load ${s.length} external diagrams`)}},Sqt=(i,s,u)=>{Xe.warn(i),wje(i)?(u&&u(i.str,i.hash),s.push({...i,message:i.str,error:i})):(u&&u(i),i instanceof Error&&s.push({str:i.message,message:i.message,hash:i.name,error:i}))},z$e=async function(i={querySelector:".mermaid"}){try{await _qt(i)}catch(s){if(wje(s)&&Xe.error(s.str),um.parseError&&um.parseError(s),!i.suppressErrors)throw Xe.error("Use the suppressErrors option to suppress these errors"),s}},_qt=async function({postRenderCallback:i,querySelector:s,nodes:u}={querySelector:".mermaid"}){const d=RC.getConfig();Xe.debug(`${i?"":"No "}Callback function found`);let p;if(u)p=u;else if(s)p=document.querySelectorAll(s);else throw new Error("Nodes and querySelector are both undefined");Xe.debug(`Found ${p.length} diagrams`),(d==null?void 0:d.startOnLoad)!==void 0&&(Xe.debug("Start On Load: "+(d==null?void 0:d.startOnLoad)),RC.updateSiteConfig({startOnLoad:d==null?void 0:d.startOnLoad}));const v=new Ao.InitIDGenerator(d.deterministicIds,d.deterministicIDSeed);let b;const y=[];for(const T of Array.from(p)){Xe.info("Rendering diagram: "+T.id);/*! Check if previously processed */if(T.getAttribute("data-processed"))continue;T.setAttribute("data-processed","true");const _=`mermaid-${v.next()}`;b=T.innerHTML,b=JM(Ao.entityDecode(b)).trim().replace(//gi,"
");const A=Ao.detectInit(b);A&&Xe.debug("Detected early reinit: ",A);try{const{svg:P,bindFunctions:R}=await U$e(_,b,T);T.innerHTML=P,i&&await i(_),R&&R(T)}catch(P){Sqt(P,y,um.parseError)}}if(y.length>0)throw y[0]},q$e=function(i){RC.initialize(i)},Aqt=async function(i,s,u){Xe.warn("mermaid.init is deprecated. Please use run instead."),i&&q$e(i);const d={postRenderCallback:u,querySelector:".mermaid"};typeof s=="string"?d.querySelector=s:s&&(s instanceof HTMLElement?d.nodes=[s]:d.nodes=s),await z$e(d)},Lqt=async(i,{lazyLoad:s=!0}={})=>{NRe(...i),s===!1&&await Cqt()},H$e=function(){if(um.startOnLoad){const{startOnLoad:i}=RC.getConfig();i&&um.run().catch(s=>Xe.error("Mermaid failed to initialize",s))}};if(typeof document<"u"){/*! + * Wait for document loaded before starting the execution + */window.addEventListener("load",H$e,!1)}const Mqt=function(i){um.parseError=i},nQ=[];let W2e=!1;const V$e=async()=>{if(!W2e){for(W2e=!0;nQ.length>0;){const i=nQ.shift();if(i)try{await i()}catch(s){Xe.error("Error executing queue",s)}}W2e=!1}},Dqt=async(i,s)=>new Promise((u,d)=>{const p=()=>new Promise((v,b)=>{RC.parse(i,s).then(y=>{v(y),u(y)},y=>{var T;Xe.error("Error parsing",y),(T=um.parseError)==null||T.call(um,y),b(y),d(y)})});nQ.push(p),V$e().catch(d)}),U$e=(i,s,u)=>new Promise((d,p)=>{const v=()=>new Promise((b,y)=>{RC.render(i,s,u).then(T=>{b(T),d(T)},T=>{var _;Xe.error("Error parsing",T),(_=um.parseError)==null||_.call(um,T),y(T),p(T)})});nQ.push(v),V$e().catch(p)}),um={startOnLoad:!0,mermaidAPI:RC,parse:Dqt,render:U$e,init:Aqt,run:z$e,registerExternalDiagrams:Lqt,initialize:q$e,parseError:void 0,contentLoaded:H$e,setParseErrorHandler:Mqt,detectType:_X};class lm{constructor(s,u,d){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=s,this.start=u,this.end=d}static range(s,u){return u?!s||!s.loc||!u.loc||s.loc.lexer!==u.loc.lexer?null:new lm(s.loc.lexer,s.loc.start,u.loc.end):s&&s.loc}}class U4{constructor(s,u){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=s,this.loc=u}range(s,u){return new U4(u,lm.range(this,s))}}class Ci{constructor(s,u){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var d="KaTeX parse error: "+s,p,v,b=u&&u.loc;if(b&&b.start<=b.end){var y=b.lexer.input;p=b.start,v=b.end,p===y.length?d+=" at end of input: ":d+=" at position "+(p+1)+": ";var T=y.slice(p,v).replace(/[^]/g,"$&̲"),_;p>15?_="…"+y.slice(p-15,p):_=y.slice(0,p);var A;v+15":">","<":"<",'"':""","'":"'"},Fqt=/[&><"']/g;function Rqt(i){return String(i).replace(Fqt,s=>Bqt[s])}var G$e=function i(s){return s.type==="ordgroup"||s.type==="color"?s.body.length===1?i(s.body[0]):s:s.type==="font"?i(s.body):s},jqt=function(s){var u=G$e(s);return u.type==="mathord"||u.type==="textord"||u.type==="atom"},$qt=function(s){if(!s)throw new Error("Expected non-null, but got "+String(s));return s},zqt=function(s){var u=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(s);return u!=null?u[1]:"_relative"},Ya={contains:Iqt,deflt:Oqt,escape:Rqt,hyphenate:Pqt,getBaseElem:G$e,isCharacterBox:jqt,protocolFromUrl:zqt},rQ={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 "},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 ",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:i=>"#"+i},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(i,s)=>(s.push(i),s)},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:i=>Math.max(0,i),cli:"--min-rule-thickness ",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:i=>Math.max(0,i),cli:"-s, --max-size ",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:i=>Math.max(0,i),cli:"-e, --max-expand ",cliProcessor:i=>i==="Infinity"?1/0:parseInt(i)},globalGroup:{type:"boolean",cli:!1}};function qqt(i){if(i.default)return i.default;var s=i.type,u=Array.isArray(s)?s[0]:s;if(typeof u!="string")return u.enum[0];switch(u){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class Y2e{constructor(s){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,s=s||{};for(var u in rQ)if(rQ.hasOwnProperty(u)){var d=rQ[u];this[u]=s[u]!==void 0?d.processor?d.processor(s[u]):s[u]:qqt(d)}}reportNonstrict(s,u,d){var p=this.strict;if(typeof p=="function"&&(p=p(s,u,d)),!(!p||p==="ignore")){if(p===!0||p==="error")throw new Ci("LaTeX-incompatible input and strict mode is set to 'error': "+(u+" ["+s+"]"),d);p==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(u+" ["+s+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+p+"': "+u+" ["+s+"]"))}}useStrictBehavior(s,u,d){var p=this.strict;if(typeof p=="function")try{p=p(s,u,d)}catch{p="error"}return!p||p==="ignore"?!1:p===!0||p==="error"?!0:p==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(u+" ["+s+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+p+"': "+u+" ["+s+"]")),!1)}isTrusted(s){s.url&&!s.protocol&&(s.protocol=Ya.protocolFromUrl(s.url));var u=typeof this.trust=="function"?this.trust(s):this.trust;return!!u}}class E9{constructor(s,u,d){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=s,this.size=u,this.cramped=d}sup(){return G4[Hqt[this.id]]}sub(){return G4[Vqt[this.id]]}fracNum(){return G4[Uqt[this.id]]}fracDen(){return G4[Gqt[this.id]]}cramp(){return G4[Kqt[this.id]]}text(){return G4[Wqt[this.id]]}isTight(){return this.size>=2}}var X2e=0,iQ=1,DD=2,L7=3,aR=4,Pv=5,ID=6,Mp=7,G4=[new E9(X2e,0,!1),new E9(iQ,0,!0),new E9(DD,1,!1),new E9(L7,1,!0),new E9(aR,2,!1),new E9(Pv,2,!0),new E9(ID,3,!1),new E9(Mp,3,!0)],Hqt=[aR,Pv,aR,Pv,ID,Mp,ID,Mp],Vqt=[Pv,Pv,Pv,Pv,Mp,Mp,Mp,Mp],Uqt=[DD,L7,aR,Pv,ID,Mp,ID,Mp],Gqt=[L7,L7,Pv,Pv,Mp,Mp,Mp,Mp],Kqt=[iQ,iQ,L7,L7,Pv,Pv,Mp,Mp],Wqt=[X2e,iQ,DD,L7,DD,L7,DD,L7],Ta={DISPLAY:G4[X2e],TEXT:G4[DD],SCRIPT:G4[aR],SCRIPTSCRIPT:G4[ID]},Q2e=[{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]]}];function Yqt(i){for(var s=0;s=p[0]&&i<=p[1])return u.name}return null}var sQ=[];Q2e.forEach(i=>i.blocks.forEach(s=>sQ.push(...s)));function K$e(i){for(var s=0;s=sQ[s]&&i<=sQ[s+1])return!0;return!1}var OD=80,Xqt=function(s,u){return"M95,"+(622+s+u)+` +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`+s/2.075+" -"+s+` +c5.3,-9.3,12,-14,20,-14 +H400000v`+(40+s)+`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+s)+" "+u+"h400000v"+(40+s)+"h-400000z"},Qqt=function(s,u){return"M263,"+(601+s+u)+`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`+s/2.084+" -"+s+` +c4.7,-7.3,11,-11,19,-11 +H40000v`+(40+s)+`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+s)+" "+u+"h400000v"+(40+s)+"h-400000z"},Jqt=function(s,u){return"M983 "+(10+s+u)+` +l`+s/3.13+" -"+s+` +c4,-6.7,10,-10,18,-10 H400000v`+(40+s)+` +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+s)+" "+u+"h400000v"+(40+s)+"h-400000z"},Zqt=function(s,u){return"M424,"+(2398+s+u)+` +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`+s/4.223+" -"+s+`c4,-6.7,10,-10,18,-10 H400000 +v`+(40+s)+`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+s)+" "+u+` +h400000v`+(40+s)+"h-400000z"},eHt=function(s,u){return"M473,"+(2713+s+u)+` +c339.3,-1799.3,509.3,-2700,510,-2702 l`+s/5.298+" -"+s+` +c3.3,-7.3,9.3,-11,18,-11 H400000v`+(40+s)+`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+s)+" "+u+"h400000v"+(40+s)+"H1017.7z"},tHt=function(s){var u=s/2;return"M400000 "+s+" H0 L"+u+" 0 l65 45 L145 "+(s-80)+" H400000z"},nHt=function(s,u,d){var p=d-54-u-s;return"M702 "+(s+u)+"H400000"+(40+s)+` +H742v`+p+`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 `+u+"H400000v"+(40+s)+"H742z"},rHt=function(s,u,d){u=1e3*u;var p="";switch(s){case"sqrtMain":p=Xqt(u,OD);break;case"sqrtSize1":p=Qqt(u,OD);break;case"sqrtSize2":p=Jqt(u,OD);break;case"sqrtSize3":p=Zqt(u,OD);break;case"sqrtSize4":p=eHt(u,OD);break;case"sqrtTall":p=nHt(u,OD,d)}return p},iHt=function(s,u){switch(s){case"⎜":return"M291 0 H417 V"+u+" H291z M291 0 H417 V"+u+" H291z";case"∣":return"M145 0 H188 V"+u+" H145z M145 0 H188 V"+u+" H145z";case"∥":return"M145 0 H188 V"+u+" H145z M145 0 H188 V"+u+" H145z"+("M367 0 H410 V"+u+" H367z M367 0 H410 V"+u+" H367z");case"⎟":return"M457 0 H583 V"+u+" H457z M457 0 H583 V"+u+" H457z";case"⎢":return"M319 0 H403 V"+u+" H319z M319 0 H403 V"+u+" H319z";case"⎥":return"M263 0 H347 V"+u+" H263z M263 0 H347 V"+u+" H263z";case"⎪":return"M384 0 H504 V"+u+" H384z M384 0 H504 V"+u+" H384z";case"⏐":return"M312 0 H355 V"+u+" H312z M312 0 H355 V"+u+" H312z";case"‖":return"M257 0 H300 V"+u+" H257z M257 0 H300 V"+u+" H257z"+("M478 0 H521 V"+u+" H478z M478 0 H521 V"+u+" H478z");default:return""}},W$e={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`},sHt=function(s,u){switch(s){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+u+` v1759 h347 v-84 +H403z M403 1759 V0 H319 V1759 v`+u+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+u+` v1759 H0 v84 H347z +M347 1759 V0 H263 V1759 v`+u+" v1759 h84z";case"vert":return"M145 15 v585 v"+u+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-u+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+u+" v585 h43z";case"doublevert":return"M145 15 v585 v"+u+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-u+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+u+` v585 h43z +M367 15 v585 v`+u+` v585 c2.667,10,9.667,15,21,15 +c10,0,16.667,-5,20,-15 v-585 v`+-u+` v-585 c-2.667,-10,-9.667,-15,-21,-15 +c-10,0,-16.667,5,-20,15z M410 15 H367 v585 v`+u+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+u+` v1715 h263 v84 H319z +MM319 602 V0 H403 V602 v`+u+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+u+` v1799 H0 v-84 H319z +MM319 602 V0 H403 V602 v`+u+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+u+` v602 h84z +M403 1759 V0 H319 V1759 v`+u+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+u+` v602 h84z +M347 1759 V0 h-84 V1759 v`+u+" 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,`+(u+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,-`+(u+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,`+(u+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,-`+(u+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.")}};class oR{constructor(s){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=s,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(s){return Ya.contains(this.classes,s)}toNode(){for(var s=document.createDocumentFragment(),u=0;uu.toText();return this.children.map(s).join("")}}var K4={"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]}},aQ={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]},Y$e={Å:"A",Ð:"D",Þ:"o",å:"a",ð:"d",þ:"o",А:"A",Б:"B",В:"B",Г:"F",Д:"A",Е:"E",Ж:"K",З:"3",И:"N",Й:"N",К:"K",Л:"N",М:"M",Н:"H",О:"O",П:"N",Р:"P",С:"C",Т:"T",У:"y",Ф:"O",Х:"X",Ц:"U",Ч:"h",Ш:"W",Щ:"W",Ъ:"B",Ы:"X",Ь:"B",Э:"3",Ю:"X",Я:"R",а:"a",б:"b",в:"a",г:"r",д:"y",е:"e",ж:"m",з:"e",и:"n",й:"n",к:"n",л:"n",м:"m",н:"n",о:"o",п:"n",р:"p",с:"c",т:"o",у:"y",ф:"b",х:"x",ц:"n",ч:"n",ш:"w",щ:"w",ъ:"a",ы:"m",ь:"a",э:"e",ю:"m",я:"r"};function aHt(i,s){K4[i]=s}function J2e(i,s,u){if(!K4[s])throw new Error("Font metrics not found for font: "+s+".");var d=i.charCodeAt(0),p=K4[s][d];if(!p&&i[0]in Y$e&&(d=Y$e[i[0]].charCodeAt(0),p=K4[s][d]),!p&&u==="text"&&K$e(d)&&(p=K4[s][77]),p)return{depth:p[0],height:p[1],italic:p[2],skew:p[3],width:p[4]}}var Z2e={};function oHt(i){var s;if(i>=5?s=0:i>=3?s=1:s=2,!Z2e[s]){var u=Z2e[s]={cssEmPerMu:aQ.quad[s]/18};for(var d in aQ)aQ.hasOwnProperty(d)&&(u[d]=aQ[d][s])}return Z2e[s]}var cHt=[[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]],X$e=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],Q$e=function(s,u){return u.size<2?s:cHt[s-1][u.size-1]};class M7{constructor(s){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=s.style,this.color=s.color,this.size=s.size||M7.BASESIZE,this.textSize=s.textSize||this.size,this.phantom=!!s.phantom,this.font=s.font||"",this.fontFamily=s.fontFamily||"",this.fontWeight=s.fontWeight||"",this.fontShape=s.fontShape||"",this.sizeMultiplier=X$e[this.size-1],this.maxSize=s.maxSize,this.minRuleThickness=s.minRuleThickness,this._fontMetrics=void 0}extend(s){var u={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 d in s)s.hasOwnProperty(d)&&(u[d]=s[d]);return new M7(u)}havingStyle(s){return this.style===s?this:this.extend({style:s,size:Q$e(this.textSize,s)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(s){return this.size===s&&this.textSize===s?this:this.extend({style:this.style.text(),size:s,textSize:s,sizeMultiplier:X$e[s-1]})}havingBaseStyle(s){s=s||this.style.text();var u=Q$e(M7.BASESIZE,s);return this.size===u&&this.textSize===M7.BASESIZE&&this.style===s?this:this.extend({style:s,size:u})}havingBaseSizing(){var s;switch(this.style.id){case 4:case 5:s=3;break;case 6:case 7:s=1;break;default:s=6}return this.extend({style:this.style.text(),size:s})}withColor(s){return this.extend({color:s})}withPhantom(){return this.extend({phantom:!0})}withFont(s){return this.extend({font:s})}withTextFontFamily(s){return this.extend({fontFamily:s,font:""})}withTextFontWeight(s){return this.extend({fontWeight:s,font:""})}withTextFontShape(s){return this.extend({fontShape:s,font:""})}sizingClasses(s){return s.size!==this.size?["sizing","reset-size"+s.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==M7.BASESIZE?["sizing","reset-size"+this.size,"size"+M7.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=oHt(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}M7.BASESIZE=6;var ebe={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},uHt={ex:!0,em:!0,mu:!0},J$e=function(s){return typeof s!="string"&&(s=s.unit),s in ebe||s in uHt||s==="ex"},Uh=function(s,u){var d;if(s.unit in ebe)d=ebe[s.unit]/u.fontMetrics().ptPerEm/u.sizeMultiplier;else if(s.unit==="mu")d=u.fontMetrics().cssEmPerMu;else{var p;if(u.style.isTight()?p=u.havingStyle(u.style.text()):p=u,s.unit==="ex")d=p.fontMetrics().xHeight;else if(s.unit==="em")d=p.fontMetrics().quad;else throw new Ci("Invalid unit: '"+s.unit+"'");p!==u&&(d*=p.sizeMultiplier/u.sizeMultiplier)}return Math.min(s.number*d,u.maxSize)},Ri=function(s){return+s.toFixed(4)+"em"},T9=function(s){return s.filter(u=>u).join(" ")},Z$e=function(s,u,d){if(this.classes=s||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=d||{},u){u.style.isTight()&&this.classes.push("mtight");var p=u.getColor();p&&(this.style.color=p)}},eze=function(s){var u=document.createElement(s);u.className=T9(this.classes);for(var d in this.style)this.style.hasOwnProperty(d)&&(u.style[d]=this.style[d]);for(var p in this.attributes)this.attributes.hasOwnProperty(p)&&u.setAttribute(p,this.attributes[p]);for(var v=0;v",u};class cR{constructor(s,u,d,p){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,Z$e.call(this,s,d,p),this.children=u||[]}setAttribute(s,u){this.attributes[s]=u}hasClass(s){return Ya.contains(this.classes,s)}toNode(){return eze.call(this,"span")}toMarkup(){return tze.call(this,"span")}}class tbe{constructor(s,u,d,p){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,Z$e.call(this,u,p),this.children=d||[],this.setAttribute("href",s)}setAttribute(s,u){this.attributes[s]=u}hasClass(s){return Ya.contains(this.classes,s)}toNode(){return eze.call(this,"a")}toMarkup(){return tze.call(this,"a")}}class lHt{constructor(s,u,d){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=u,this.src=s,this.classes=["mord"],this.style=d}hasClass(s){return Ya.contains(this.classes,s)}toNode(){var s=document.createElement("img");s.src=this.src,s.alt=this.alt,s.className="mord";for(var u in this.style)this.style.hasOwnProperty(u)&&(s.style[u]=this.style[u]);return s}toMarkup(){var s=""+this.alt+"0&&(u=document.createElement("span"),u.style.marginRight=Ri(this.italic)),this.classes.length>0&&(u=u||document.createElement("span"),u.className=T9(this.classes));for(var d in this.style)this.style.hasOwnProperty(d)&&(u=u||document.createElement("span"),u.style[d]=this.style[d]);return u?(u.appendChild(s),u):s}toMarkup(){var s=!1,u="0&&(d+="margin-right:"+this.italic+"em;");for(var p in this.style)this.style.hasOwnProperty(p)&&(d+=Ya.hyphenate(p)+":"+this.style[p]+";");d&&(s=!0,u+=' style="'+Ya.escape(d)+'"');var v=Ya.escape(this.text);return s?(u+=">",u+=v,u+="",u):v}}class D7{constructor(s,u){this.children=void 0,this.attributes=void 0,this.children=s||[],this.attributes=u||{}}toNode(){var s="http://www.w3.org/2000/svg",u=document.createElementNS(s,"svg");for(var d in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,d)&&u.setAttribute(d,this.attributes[d]);for(var p=0;p":""}}class nbe{constructor(s){this.attributes=void 0,this.attributes=s||{}}toNode(){var s="http://www.w3.org/2000/svg",u=document.createElementNS(s,"line");for(var d in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,d)&&u.setAttribute(d,this.attributes[d]);return u}toMarkup(){var s=" but got "+String(i)+".")}var dHt={bin:1,close:1,inner:1,open:1,punct:1,rel:1},gHt={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},Ul={math:{},text:{}};function we(i,s,u,d,p,v){Ul[i][p]={font:s,group:u,replace:d},v&&d&&(Ul[i][d]=Ul[i][p])}var Ae="math",si="text",Ue="main",$t="ams",wh="accent-token",ls="bin",Dp="close",ND="inner",Ca="mathord",N0="op-token",hm="open",oQ="punct",Ht="rel",I7="spacing",mn="textord";we(Ae,Ue,Ht,"≡","\\equiv",!0),we(Ae,Ue,Ht,"≺","\\prec",!0),we(Ae,Ue,Ht,"≻","\\succ",!0),we(Ae,Ue,Ht,"∼","\\sim",!0),we(Ae,Ue,Ht,"⊥","\\perp"),we(Ae,Ue,Ht,"⪯","\\preceq",!0),we(Ae,Ue,Ht,"⪰","\\succeq",!0),we(Ae,Ue,Ht,"≃","\\simeq",!0),we(Ae,Ue,Ht,"∣","\\mid",!0),we(Ae,Ue,Ht,"≪","\\ll",!0),we(Ae,Ue,Ht,"≫","\\gg",!0),we(Ae,Ue,Ht,"≍","\\asymp",!0),we(Ae,Ue,Ht,"∥","\\parallel"),we(Ae,Ue,Ht,"⋈","\\bowtie",!0),we(Ae,Ue,Ht,"⌣","\\smile",!0),we(Ae,Ue,Ht,"⊑","\\sqsubseteq",!0),we(Ae,Ue,Ht,"⊒","\\sqsupseteq",!0),we(Ae,Ue,Ht,"≐","\\doteq",!0),we(Ae,Ue,Ht,"⌢","\\frown",!0),we(Ae,Ue,Ht,"∋","\\ni",!0),we(Ae,Ue,Ht,"∝","\\propto",!0),we(Ae,Ue,Ht,"⊢","\\vdash",!0),we(Ae,Ue,Ht,"⊣","\\dashv",!0),we(Ae,Ue,Ht,"∋","\\owns"),we(Ae,Ue,oQ,".","\\ldotp"),we(Ae,Ue,oQ,"⋅","\\cdotp"),we(Ae,Ue,mn,"#","\\#"),we(si,Ue,mn,"#","\\#"),we(Ae,Ue,mn,"&","\\&"),we(si,Ue,mn,"&","\\&"),we(Ae,Ue,mn,"ℵ","\\aleph",!0),we(Ae,Ue,mn,"∀","\\forall",!0),we(Ae,Ue,mn,"ℏ","\\hbar",!0),we(Ae,Ue,mn,"∃","\\exists",!0),we(Ae,Ue,mn,"∇","\\nabla",!0),we(Ae,Ue,mn,"♭","\\flat",!0),we(Ae,Ue,mn,"ℓ","\\ell",!0),we(Ae,Ue,mn,"♮","\\natural",!0),we(Ae,Ue,mn,"♣","\\clubsuit",!0),we(Ae,Ue,mn,"℘","\\wp",!0),we(Ae,Ue,mn,"♯","\\sharp",!0),we(Ae,Ue,mn,"♢","\\diamondsuit",!0),we(Ae,Ue,mn,"ℜ","\\Re",!0),we(Ae,Ue,mn,"♡","\\heartsuit",!0),we(Ae,Ue,mn,"ℑ","\\Im",!0),we(Ae,Ue,mn,"♠","\\spadesuit",!0),we(Ae,Ue,mn,"§","\\S",!0),we(si,Ue,mn,"§","\\S"),we(Ae,Ue,mn,"¶","\\P",!0),we(si,Ue,mn,"¶","\\P"),we(Ae,Ue,mn,"†","\\dag"),we(si,Ue,mn,"†","\\dag"),we(si,Ue,mn,"†","\\textdagger"),we(Ae,Ue,mn,"‡","\\ddag"),we(si,Ue,mn,"‡","\\ddag"),we(si,Ue,mn,"‡","\\textdaggerdbl"),we(Ae,Ue,Dp,"⎱","\\rmoustache",!0),we(Ae,Ue,hm,"⎰","\\lmoustache",!0),we(Ae,Ue,Dp,"⟯","\\rgroup",!0),we(Ae,Ue,hm,"⟮","\\lgroup",!0),we(Ae,Ue,ls,"∓","\\mp",!0),we(Ae,Ue,ls,"⊖","\\ominus",!0),we(Ae,Ue,ls,"⊎","\\uplus",!0),we(Ae,Ue,ls,"⊓","\\sqcap",!0),we(Ae,Ue,ls,"∗","\\ast"),we(Ae,Ue,ls,"⊔","\\sqcup",!0),we(Ae,Ue,ls,"◯","\\bigcirc",!0),we(Ae,Ue,ls,"∙","\\bullet",!0),we(Ae,Ue,ls,"‡","\\ddagger"),we(Ae,Ue,ls,"≀","\\wr",!0),we(Ae,Ue,ls,"⨿","\\amalg"),we(Ae,Ue,ls,"&","\\And"),we(Ae,Ue,Ht,"⟵","\\longleftarrow",!0),we(Ae,Ue,Ht,"⇐","\\Leftarrow",!0),we(Ae,Ue,Ht,"⟸","\\Longleftarrow",!0),we(Ae,Ue,Ht,"⟶","\\longrightarrow",!0),we(Ae,Ue,Ht,"⇒","\\Rightarrow",!0),we(Ae,Ue,Ht,"⟹","\\Longrightarrow",!0),we(Ae,Ue,Ht,"↔","\\leftrightarrow",!0),we(Ae,Ue,Ht,"⟷","\\longleftrightarrow",!0),we(Ae,Ue,Ht,"⇔","\\Leftrightarrow",!0),we(Ae,Ue,Ht,"⟺","\\Longleftrightarrow",!0),we(Ae,Ue,Ht,"↦","\\mapsto",!0),we(Ae,Ue,Ht,"⟼","\\longmapsto",!0),we(Ae,Ue,Ht,"↗","\\nearrow",!0),we(Ae,Ue,Ht,"↩","\\hookleftarrow",!0),we(Ae,Ue,Ht,"↪","\\hookrightarrow",!0),we(Ae,Ue,Ht,"↘","\\searrow",!0),we(Ae,Ue,Ht,"↼","\\leftharpoonup",!0),we(Ae,Ue,Ht,"⇀","\\rightharpoonup",!0),we(Ae,Ue,Ht,"↙","\\swarrow",!0),we(Ae,Ue,Ht,"↽","\\leftharpoondown",!0),we(Ae,Ue,Ht,"⇁","\\rightharpoondown",!0),we(Ae,Ue,Ht,"↖","\\nwarrow",!0),we(Ae,Ue,Ht,"⇌","\\rightleftharpoons",!0),we(Ae,$t,Ht,"≮","\\nless",!0),we(Ae,$t,Ht,"","\\@nleqslant"),we(Ae,$t,Ht,"","\\@nleqq"),we(Ae,$t,Ht,"⪇","\\lneq",!0),we(Ae,$t,Ht,"≨","\\lneqq",!0),we(Ae,$t,Ht,"","\\@lvertneqq"),we(Ae,$t,Ht,"⋦","\\lnsim",!0),we(Ae,$t,Ht,"⪉","\\lnapprox",!0),we(Ae,$t,Ht,"⊀","\\nprec",!0),we(Ae,$t,Ht,"⋠","\\npreceq",!0),we(Ae,$t,Ht,"⋨","\\precnsim",!0),we(Ae,$t,Ht,"⪹","\\precnapprox",!0),we(Ae,$t,Ht,"≁","\\nsim",!0),we(Ae,$t,Ht,"","\\@nshortmid"),we(Ae,$t,Ht,"∤","\\nmid",!0),we(Ae,$t,Ht,"⊬","\\nvdash",!0),we(Ae,$t,Ht,"⊭","\\nvDash",!0),we(Ae,$t,Ht,"⋪","\\ntriangleleft"),we(Ae,$t,Ht,"⋬","\\ntrianglelefteq",!0),we(Ae,$t,Ht,"⊊","\\subsetneq",!0),we(Ae,$t,Ht,"","\\@varsubsetneq"),we(Ae,$t,Ht,"⫋","\\subsetneqq",!0),we(Ae,$t,Ht,"","\\@varsubsetneqq"),we(Ae,$t,Ht,"≯","\\ngtr",!0),we(Ae,$t,Ht,"","\\@ngeqslant"),we(Ae,$t,Ht,"","\\@ngeqq"),we(Ae,$t,Ht,"⪈","\\gneq",!0),we(Ae,$t,Ht,"≩","\\gneqq",!0),we(Ae,$t,Ht,"","\\@gvertneqq"),we(Ae,$t,Ht,"⋧","\\gnsim",!0),we(Ae,$t,Ht,"⪊","\\gnapprox",!0),we(Ae,$t,Ht,"⊁","\\nsucc",!0),we(Ae,$t,Ht,"⋡","\\nsucceq",!0),we(Ae,$t,Ht,"⋩","\\succnsim",!0),we(Ae,$t,Ht,"⪺","\\succnapprox",!0),we(Ae,$t,Ht,"≆","\\ncong",!0),we(Ae,$t,Ht,"","\\@nshortparallel"),we(Ae,$t,Ht,"∦","\\nparallel",!0),we(Ae,$t,Ht,"⊯","\\nVDash",!0),we(Ae,$t,Ht,"⋫","\\ntriangleright"),we(Ae,$t,Ht,"⋭","\\ntrianglerighteq",!0),we(Ae,$t,Ht,"","\\@nsupseteqq"),we(Ae,$t,Ht,"⊋","\\supsetneq",!0),we(Ae,$t,Ht,"","\\@varsupsetneq"),we(Ae,$t,Ht,"⫌","\\supsetneqq",!0),we(Ae,$t,Ht,"","\\@varsupsetneqq"),we(Ae,$t,Ht,"⊮","\\nVdash",!0),we(Ae,$t,Ht,"⪵","\\precneqq",!0),we(Ae,$t,Ht,"⪶","\\succneqq",!0),we(Ae,$t,Ht,"","\\@nsubseteqq"),we(Ae,$t,ls,"⊴","\\unlhd"),we(Ae,$t,ls,"⊵","\\unrhd"),we(Ae,$t,Ht,"↚","\\nleftarrow",!0),we(Ae,$t,Ht,"↛","\\nrightarrow",!0),we(Ae,$t,Ht,"⇍","\\nLeftarrow",!0),we(Ae,$t,Ht,"⇏","\\nRightarrow",!0),we(Ae,$t,Ht,"↮","\\nleftrightarrow",!0),we(Ae,$t,Ht,"⇎","\\nLeftrightarrow",!0),we(Ae,$t,Ht,"△","\\vartriangle"),we(Ae,$t,mn,"ℏ","\\hslash"),we(Ae,$t,mn,"▽","\\triangledown"),we(Ae,$t,mn,"◊","\\lozenge"),we(Ae,$t,mn,"Ⓢ","\\circledS"),we(Ae,$t,mn,"®","\\circledR"),we(si,$t,mn,"®","\\circledR"),we(Ae,$t,mn,"∡","\\measuredangle",!0),we(Ae,$t,mn,"∄","\\nexists"),we(Ae,$t,mn,"℧","\\mho"),we(Ae,$t,mn,"Ⅎ","\\Finv",!0),we(Ae,$t,mn,"⅁","\\Game",!0),we(Ae,$t,mn,"‵","\\backprime"),we(Ae,$t,mn,"▲","\\blacktriangle"),we(Ae,$t,mn,"▼","\\blacktriangledown"),we(Ae,$t,mn,"■","\\blacksquare"),we(Ae,$t,mn,"⧫","\\blacklozenge"),we(Ae,$t,mn,"★","\\bigstar"),we(Ae,$t,mn,"∢","\\sphericalangle",!0),we(Ae,$t,mn,"∁","\\complement",!0),we(Ae,$t,mn,"ð","\\eth",!0),we(si,Ue,mn,"ð","ð"),we(Ae,$t,mn,"╱","\\diagup"),we(Ae,$t,mn,"╲","\\diagdown"),we(Ae,$t,mn,"□","\\square"),we(Ae,$t,mn,"□","\\Box"),we(Ae,$t,mn,"◊","\\Diamond"),we(Ae,$t,mn,"¥","\\yen",!0),we(si,$t,mn,"¥","\\yen",!0),we(Ae,$t,mn,"✓","\\checkmark",!0),we(si,$t,mn,"✓","\\checkmark"),we(Ae,$t,mn,"ℶ","\\beth",!0),we(Ae,$t,mn,"ℸ","\\daleth",!0),we(Ae,$t,mn,"ℷ","\\gimel",!0),we(Ae,$t,mn,"ϝ","\\digamma",!0),we(Ae,$t,mn,"ϰ","\\varkappa"),we(Ae,$t,hm,"┌","\\@ulcorner",!0),we(Ae,$t,Dp,"┐","\\@urcorner",!0),we(Ae,$t,hm,"└","\\@llcorner",!0),we(Ae,$t,Dp,"┘","\\@lrcorner",!0),we(Ae,$t,Ht,"≦","\\leqq",!0),we(Ae,$t,Ht,"⩽","\\leqslant",!0),we(Ae,$t,Ht,"⪕","\\eqslantless",!0),we(Ae,$t,Ht,"≲","\\lesssim",!0),we(Ae,$t,Ht,"⪅","\\lessapprox",!0),we(Ae,$t,Ht,"≊","\\approxeq",!0),we(Ae,$t,ls,"⋖","\\lessdot"),we(Ae,$t,Ht,"⋘","\\lll",!0),we(Ae,$t,Ht,"≶","\\lessgtr",!0),we(Ae,$t,Ht,"⋚","\\lesseqgtr",!0),we(Ae,$t,Ht,"⪋","\\lesseqqgtr",!0),we(Ae,$t,Ht,"≑","\\doteqdot"),we(Ae,$t,Ht,"≓","\\risingdotseq",!0),we(Ae,$t,Ht,"≒","\\fallingdotseq",!0),we(Ae,$t,Ht,"∽","\\backsim",!0),we(Ae,$t,Ht,"⋍","\\backsimeq",!0),we(Ae,$t,Ht,"⫅","\\subseteqq",!0),we(Ae,$t,Ht,"⋐","\\Subset",!0),we(Ae,$t,Ht,"⊏","\\sqsubset",!0),we(Ae,$t,Ht,"≼","\\preccurlyeq",!0),we(Ae,$t,Ht,"⋞","\\curlyeqprec",!0),we(Ae,$t,Ht,"≾","\\precsim",!0),we(Ae,$t,Ht,"⪷","\\precapprox",!0),we(Ae,$t,Ht,"⊲","\\vartriangleleft"),we(Ae,$t,Ht,"⊴","\\trianglelefteq"),we(Ae,$t,Ht,"⊨","\\vDash",!0),we(Ae,$t,Ht,"⊪","\\Vvdash",!0),we(Ae,$t,Ht,"⌣","\\smallsmile"),we(Ae,$t,Ht,"⌢","\\smallfrown"),we(Ae,$t,Ht,"≏","\\bumpeq",!0),we(Ae,$t,Ht,"≎","\\Bumpeq",!0),we(Ae,$t,Ht,"≧","\\geqq",!0),we(Ae,$t,Ht,"⩾","\\geqslant",!0),we(Ae,$t,Ht,"⪖","\\eqslantgtr",!0),we(Ae,$t,Ht,"≳","\\gtrsim",!0),we(Ae,$t,Ht,"⪆","\\gtrapprox",!0),we(Ae,$t,ls,"⋗","\\gtrdot"),we(Ae,$t,Ht,"⋙","\\ggg",!0),we(Ae,$t,Ht,"≷","\\gtrless",!0),we(Ae,$t,Ht,"⋛","\\gtreqless",!0),we(Ae,$t,Ht,"⪌","\\gtreqqless",!0),we(Ae,$t,Ht,"≖","\\eqcirc",!0),we(Ae,$t,Ht,"≗","\\circeq",!0),we(Ae,$t,Ht,"≜","\\triangleq",!0),we(Ae,$t,Ht,"∼","\\thicksim"),we(Ae,$t,Ht,"≈","\\thickapprox"),we(Ae,$t,Ht,"⫆","\\supseteqq",!0),we(Ae,$t,Ht,"⋑","\\Supset",!0),we(Ae,$t,Ht,"⊐","\\sqsupset",!0),we(Ae,$t,Ht,"≽","\\succcurlyeq",!0),we(Ae,$t,Ht,"⋟","\\curlyeqsucc",!0),we(Ae,$t,Ht,"≿","\\succsim",!0),we(Ae,$t,Ht,"⪸","\\succapprox",!0),we(Ae,$t,Ht,"⊳","\\vartriangleright"),we(Ae,$t,Ht,"⊵","\\trianglerighteq"),we(Ae,$t,Ht,"⊩","\\Vdash",!0),we(Ae,$t,Ht,"∣","\\shortmid"),we(Ae,$t,Ht,"∥","\\shortparallel"),we(Ae,$t,Ht,"≬","\\between",!0),we(Ae,$t,Ht,"⋔","\\pitchfork",!0),we(Ae,$t,Ht,"∝","\\varpropto"),we(Ae,$t,Ht,"◀","\\blacktriangleleft"),we(Ae,$t,Ht,"∴","\\therefore",!0),we(Ae,$t,Ht,"∍","\\backepsilon"),we(Ae,$t,Ht,"▶","\\blacktriangleright"),we(Ae,$t,Ht,"∵","\\because",!0),we(Ae,$t,Ht,"⋘","\\llless"),we(Ae,$t,Ht,"⋙","\\gggtr"),we(Ae,$t,ls,"⊲","\\lhd"),we(Ae,$t,ls,"⊳","\\rhd"),we(Ae,$t,Ht,"≂","\\eqsim",!0),we(Ae,Ue,Ht,"⋈","\\Join"),we(Ae,$t,Ht,"≑","\\Doteq",!0),we(Ae,$t,ls,"∔","\\dotplus",!0),we(Ae,$t,ls,"∖","\\smallsetminus"),we(Ae,$t,ls,"⋒","\\Cap",!0),we(Ae,$t,ls,"⋓","\\Cup",!0),we(Ae,$t,ls,"⩞","\\doublebarwedge",!0),we(Ae,$t,ls,"⊟","\\boxminus",!0),we(Ae,$t,ls,"⊞","\\boxplus",!0),we(Ae,$t,ls,"⋇","\\divideontimes",!0),we(Ae,$t,ls,"⋉","\\ltimes",!0),we(Ae,$t,ls,"⋊","\\rtimes",!0),we(Ae,$t,ls,"⋋","\\leftthreetimes",!0),we(Ae,$t,ls,"⋌","\\rightthreetimes",!0),we(Ae,$t,ls,"⋏","\\curlywedge",!0),we(Ae,$t,ls,"⋎","\\curlyvee",!0),we(Ae,$t,ls,"⊝","\\circleddash",!0),we(Ae,$t,ls,"⊛","\\circledast",!0),we(Ae,$t,ls,"⋅","\\centerdot"),we(Ae,$t,ls,"⊺","\\intercal",!0),we(Ae,$t,ls,"⋒","\\doublecap"),we(Ae,$t,ls,"⋓","\\doublecup"),we(Ae,$t,ls,"⊠","\\boxtimes",!0),we(Ae,$t,Ht,"⇢","\\dashrightarrow",!0),we(Ae,$t,Ht,"⇠","\\dashleftarrow",!0),we(Ae,$t,Ht,"⇇","\\leftleftarrows",!0),we(Ae,$t,Ht,"⇆","\\leftrightarrows",!0),we(Ae,$t,Ht,"⇚","\\Lleftarrow",!0),we(Ae,$t,Ht,"↞","\\twoheadleftarrow",!0),we(Ae,$t,Ht,"↢","\\leftarrowtail",!0),we(Ae,$t,Ht,"↫","\\looparrowleft",!0),we(Ae,$t,Ht,"⇋","\\leftrightharpoons",!0),we(Ae,$t,Ht,"↶","\\curvearrowleft",!0),we(Ae,$t,Ht,"↺","\\circlearrowleft",!0),we(Ae,$t,Ht,"↰","\\Lsh",!0),we(Ae,$t,Ht,"⇈","\\upuparrows",!0),we(Ae,$t,Ht,"↿","\\upharpoonleft",!0),we(Ae,$t,Ht,"⇃","\\downharpoonleft",!0),we(Ae,Ue,Ht,"⊶","\\origof",!0),we(Ae,Ue,Ht,"⊷","\\imageof",!0),we(Ae,$t,Ht,"⊸","\\multimap",!0),we(Ae,$t,Ht,"↭","\\leftrightsquigarrow",!0),we(Ae,$t,Ht,"⇉","\\rightrightarrows",!0),we(Ae,$t,Ht,"⇄","\\rightleftarrows",!0),we(Ae,$t,Ht,"↠","\\twoheadrightarrow",!0),we(Ae,$t,Ht,"↣","\\rightarrowtail",!0),we(Ae,$t,Ht,"↬","\\looparrowright",!0),we(Ae,$t,Ht,"↷","\\curvearrowright",!0),we(Ae,$t,Ht,"↻","\\circlearrowright",!0),we(Ae,$t,Ht,"↱","\\Rsh",!0),we(Ae,$t,Ht,"⇊","\\downdownarrows",!0),we(Ae,$t,Ht,"↾","\\upharpoonright",!0),we(Ae,$t,Ht,"⇂","\\downharpoonright",!0),we(Ae,$t,Ht,"⇝","\\rightsquigarrow",!0),we(Ae,$t,Ht,"⇝","\\leadsto"),we(Ae,$t,Ht,"⇛","\\Rrightarrow",!0),we(Ae,$t,Ht,"↾","\\restriction"),we(Ae,Ue,mn,"‘","`"),we(Ae,Ue,mn,"$","\\$"),we(si,Ue,mn,"$","\\$"),we(si,Ue,mn,"$","\\textdollar"),we(Ae,Ue,mn,"%","\\%"),we(si,Ue,mn,"%","\\%"),we(Ae,Ue,mn,"_","\\_"),we(si,Ue,mn,"_","\\_"),we(si,Ue,mn,"_","\\textunderscore"),we(Ae,Ue,mn,"∠","\\angle",!0),we(Ae,Ue,mn,"∞","\\infty",!0),we(Ae,Ue,mn,"′","\\prime"),we(Ae,Ue,mn,"△","\\triangle"),we(Ae,Ue,mn,"Γ","\\Gamma",!0),we(Ae,Ue,mn,"Δ","\\Delta",!0),we(Ae,Ue,mn,"Θ","\\Theta",!0),we(Ae,Ue,mn,"Λ","\\Lambda",!0),we(Ae,Ue,mn,"Ξ","\\Xi",!0),we(Ae,Ue,mn,"Π","\\Pi",!0),we(Ae,Ue,mn,"Σ","\\Sigma",!0),we(Ae,Ue,mn,"Υ","\\Upsilon",!0),we(Ae,Ue,mn,"Φ","\\Phi",!0),we(Ae,Ue,mn,"Ψ","\\Psi",!0),we(Ae,Ue,mn,"Ω","\\Omega",!0),we(Ae,Ue,mn,"A","Α"),we(Ae,Ue,mn,"B","Β"),we(Ae,Ue,mn,"E","Ε"),we(Ae,Ue,mn,"Z","Ζ"),we(Ae,Ue,mn,"H","Η"),we(Ae,Ue,mn,"I","Ι"),we(Ae,Ue,mn,"K","Κ"),we(Ae,Ue,mn,"M","Μ"),we(Ae,Ue,mn,"N","Ν"),we(Ae,Ue,mn,"O","Ο"),we(Ae,Ue,mn,"P","Ρ"),we(Ae,Ue,mn,"T","Τ"),we(Ae,Ue,mn,"X","Χ"),we(Ae,Ue,mn,"¬","\\neg",!0),we(Ae,Ue,mn,"¬","\\lnot"),we(Ae,Ue,mn,"⊤","\\top"),we(Ae,Ue,mn,"⊥","\\bot"),we(Ae,Ue,mn,"∅","\\emptyset"),we(Ae,$t,mn,"∅","\\varnothing"),we(Ae,Ue,Ca,"α","\\alpha",!0),we(Ae,Ue,Ca,"β","\\beta",!0),we(Ae,Ue,Ca,"γ","\\gamma",!0),we(Ae,Ue,Ca,"δ","\\delta",!0),we(Ae,Ue,Ca,"ϵ","\\epsilon",!0),we(Ae,Ue,Ca,"ζ","\\zeta",!0),we(Ae,Ue,Ca,"η","\\eta",!0),we(Ae,Ue,Ca,"θ","\\theta",!0),we(Ae,Ue,Ca,"ι","\\iota",!0),we(Ae,Ue,Ca,"κ","\\kappa",!0),we(Ae,Ue,Ca,"λ","\\lambda",!0),we(Ae,Ue,Ca,"μ","\\mu",!0),we(Ae,Ue,Ca,"ν","\\nu",!0),we(Ae,Ue,Ca,"ξ","\\xi",!0),we(Ae,Ue,Ca,"ο","\\omicron",!0),we(Ae,Ue,Ca,"π","\\pi",!0),we(Ae,Ue,Ca,"ρ","\\rho",!0),we(Ae,Ue,Ca,"σ","\\sigma",!0),we(Ae,Ue,Ca,"τ","\\tau",!0),we(Ae,Ue,Ca,"υ","\\upsilon",!0),we(Ae,Ue,Ca,"ϕ","\\phi",!0),we(Ae,Ue,Ca,"χ","\\chi",!0),we(Ae,Ue,Ca,"ψ","\\psi",!0),we(Ae,Ue,Ca,"ω","\\omega",!0),we(Ae,Ue,Ca,"ε","\\varepsilon",!0),we(Ae,Ue,Ca,"ϑ","\\vartheta",!0),we(Ae,Ue,Ca,"ϖ","\\varpi",!0),we(Ae,Ue,Ca,"ϱ","\\varrho",!0),we(Ae,Ue,Ca,"ς","\\varsigma",!0),we(Ae,Ue,Ca,"φ","\\varphi",!0),we(Ae,Ue,ls,"∗","*",!0),we(Ae,Ue,ls,"+","+"),we(Ae,Ue,ls,"−","-",!0),we(Ae,Ue,ls,"⋅","\\cdot",!0),we(Ae,Ue,ls,"∘","\\circ",!0),we(Ae,Ue,ls,"÷","\\div",!0),we(Ae,Ue,ls,"±","\\pm",!0),we(Ae,Ue,ls,"×","\\times",!0),we(Ae,Ue,ls,"∩","\\cap",!0),we(Ae,Ue,ls,"∪","\\cup",!0),we(Ae,Ue,ls,"∖","\\setminus",!0),we(Ae,Ue,ls,"∧","\\land"),we(Ae,Ue,ls,"∨","\\lor"),we(Ae,Ue,ls,"∧","\\wedge",!0),we(Ae,Ue,ls,"∨","\\vee",!0),we(Ae,Ue,mn,"√","\\surd"),we(Ae,Ue,hm,"⟨","\\langle",!0),we(Ae,Ue,hm,"∣","\\lvert"),we(Ae,Ue,hm,"∥","\\lVert"),we(Ae,Ue,Dp,"?","?"),we(Ae,Ue,Dp,"!","!"),we(Ae,Ue,Dp,"⟩","\\rangle",!0),we(Ae,Ue,Dp,"∣","\\rvert"),we(Ae,Ue,Dp,"∥","\\rVert"),we(Ae,Ue,Ht,"=","="),we(Ae,Ue,Ht,":",":"),we(Ae,Ue,Ht,"≈","\\approx",!0),we(Ae,Ue,Ht,"≅","\\cong",!0),we(Ae,Ue,Ht,"≥","\\ge"),we(Ae,Ue,Ht,"≥","\\geq",!0),we(Ae,Ue,Ht,"←","\\gets"),we(Ae,Ue,Ht,">","\\gt",!0),we(Ae,Ue,Ht,"∈","\\in",!0),we(Ae,Ue,Ht,"","\\@not"),we(Ae,Ue,Ht,"⊂","\\subset",!0),we(Ae,Ue,Ht,"⊃","\\supset",!0),we(Ae,Ue,Ht,"⊆","\\subseteq",!0),we(Ae,Ue,Ht,"⊇","\\supseteq",!0),we(Ae,$t,Ht,"⊈","\\nsubseteq",!0),we(Ae,$t,Ht,"⊉","\\nsupseteq",!0),we(Ae,Ue,Ht,"⊨","\\models"),we(Ae,Ue,Ht,"←","\\leftarrow",!0),we(Ae,Ue,Ht,"≤","\\le"),we(Ae,Ue,Ht,"≤","\\leq",!0),we(Ae,Ue,Ht,"<","\\lt",!0),we(Ae,Ue,Ht,"→","\\rightarrow",!0),we(Ae,Ue,Ht,"→","\\to"),we(Ae,$t,Ht,"≱","\\ngeq",!0),we(Ae,$t,Ht,"≰","\\nleq",!0),we(Ae,Ue,I7," ","\\ "),we(Ae,Ue,I7," ","\\space"),we(Ae,Ue,I7," ","\\nobreakspace"),we(si,Ue,I7," ","\\ "),we(si,Ue,I7," "," "),we(si,Ue,I7," ","\\space"),we(si,Ue,I7," ","\\nobreakspace"),we(Ae,Ue,I7,null,"\\nobreak"),we(Ae,Ue,I7,null,"\\allowbreak"),we(Ae,Ue,oQ,",",","),we(Ae,Ue,oQ,";",";"),we(Ae,$t,ls,"⊼","\\barwedge",!0),we(Ae,$t,ls,"⊻","\\veebar",!0),we(Ae,Ue,ls,"⊙","\\odot",!0),we(Ae,Ue,ls,"⊕","\\oplus",!0),we(Ae,Ue,ls,"⊗","\\otimes",!0),we(Ae,Ue,mn,"∂","\\partial",!0),we(Ae,Ue,ls,"⊘","\\oslash",!0),we(Ae,$t,ls,"⊚","\\circledcirc",!0),we(Ae,$t,ls,"⊡","\\boxdot",!0),we(Ae,Ue,ls,"△","\\bigtriangleup"),we(Ae,Ue,ls,"▽","\\bigtriangledown"),we(Ae,Ue,ls,"†","\\dagger"),we(Ae,Ue,ls,"⋄","\\diamond"),we(Ae,Ue,ls,"⋆","\\star"),we(Ae,Ue,ls,"◃","\\triangleleft"),we(Ae,Ue,ls,"▹","\\triangleright"),we(Ae,Ue,hm,"{","\\{"),we(si,Ue,mn,"{","\\{"),we(si,Ue,mn,"{","\\textbraceleft"),we(Ae,Ue,Dp,"}","\\}"),we(si,Ue,mn,"}","\\}"),we(si,Ue,mn,"}","\\textbraceright"),we(Ae,Ue,hm,"{","\\lbrace"),we(Ae,Ue,Dp,"}","\\rbrace"),we(Ae,Ue,hm,"[","\\lbrack",!0),we(si,Ue,mn,"[","\\lbrack",!0),we(Ae,Ue,Dp,"]","\\rbrack",!0),we(si,Ue,mn,"]","\\rbrack",!0),we(Ae,Ue,hm,"(","\\lparen",!0),we(Ae,Ue,Dp,")","\\rparen",!0),we(si,Ue,mn,"<","\\textless",!0),we(si,Ue,mn,">","\\textgreater",!0),we(Ae,Ue,hm,"⌊","\\lfloor",!0),we(Ae,Ue,Dp,"⌋","\\rfloor",!0),we(Ae,Ue,hm,"⌈","\\lceil",!0),we(Ae,Ue,Dp,"⌉","\\rceil",!0),we(Ae,Ue,mn,"\\","\\backslash"),we(Ae,Ue,mn,"∣","|"),we(Ae,Ue,mn,"∣","\\vert"),we(si,Ue,mn,"|","\\textbar",!0),we(Ae,Ue,mn,"∥","\\|"),we(Ae,Ue,mn,"∥","\\Vert"),we(si,Ue,mn,"∥","\\textbardbl"),we(si,Ue,mn,"~","\\textasciitilde"),we(si,Ue,mn,"\\","\\textbackslash"),we(si,Ue,mn,"^","\\textasciicircum"),we(Ae,Ue,Ht,"↑","\\uparrow",!0),we(Ae,Ue,Ht,"⇑","\\Uparrow",!0),we(Ae,Ue,Ht,"↓","\\downarrow",!0),we(Ae,Ue,Ht,"⇓","\\Downarrow",!0),we(Ae,Ue,Ht,"↕","\\updownarrow",!0),we(Ae,Ue,Ht,"⇕","\\Updownarrow",!0),we(Ae,Ue,N0,"∐","\\coprod"),we(Ae,Ue,N0,"⋁","\\bigvee"),we(Ae,Ue,N0,"⋀","\\bigwedge"),we(Ae,Ue,N0,"⨄","\\biguplus"),we(Ae,Ue,N0,"⋂","\\bigcap"),we(Ae,Ue,N0,"⋃","\\bigcup"),we(Ae,Ue,N0,"∫","\\int"),we(Ae,Ue,N0,"∫","\\intop"),we(Ae,Ue,N0,"∬","\\iint"),we(Ae,Ue,N0,"∭","\\iiint"),we(Ae,Ue,N0,"∏","\\prod"),we(Ae,Ue,N0,"∑","\\sum"),we(Ae,Ue,N0,"⨂","\\bigotimes"),we(Ae,Ue,N0,"⨁","\\bigoplus"),we(Ae,Ue,N0,"⨀","\\bigodot"),we(Ae,Ue,N0,"∮","\\oint"),we(Ae,Ue,N0,"∯","\\oiint"),we(Ae,Ue,N0,"∰","\\oiiint"),we(Ae,Ue,N0,"⨆","\\bigsqcup"),we(Ae,Ue,N0,"∫","\\smallint"),we(si,Ue,ND,"…","\\textellipsis"),we(Ae,Ue,ND,"…","\\mathellipsis"),we(si,Ue,ND,"…","\\ldots",!0),we(Ae,Ue,ND,"…","\\ldots",!0),we(Ae,Ue,ND,"⋯","\\@cdots",!0),we(Ae,Ue,ND,"⋱","\\ddots",!0),we(Ae,Ue,mn,"⋮","\\varvdots"),we(Ae,Ue,wh,"ˊ","\\acute"),we(Ae,Ue,wh,"ˋ","\\grave"),we(Ae,Ue,wh,"¨","\\ddot"),we(Ae,Ue,wh,"~","\\tilde"),we(Ae,Ue,wh,"ˉ","\\bar"),we(Ae,Ue,wh,"˘","\\breve"),we(Ae,Ue,wh,"ˇ","\\check"),we(Ae,Ue,wh,"^","\\hat"),we(Ae,Ue,wh,"⃗","\\vec"),we(Ae,Ue,wh,"˙","\\dot"),we(Ae,Ue,wh,"˚","\\mathring"),we(Ae,Ue,Ca,"","\\@imath"),we(Ae,Ue,Ca,"","\\@jmath"),we(Ae,Ue,mn,"ı","ı"),we(Ae,Ue,mn,"ȷ","ȷ"),we(si,Ue,mn,"ı","\\i",!0),we(si,Ue,mn,"ȷ","\\j",!0),we(si,Ue,mn,"ß","\\ss",!0),we(si,Ue,mn,"æ","\\ae",!0),we(si,Ue,mn,"œ","\\oe",!0),we(si,Ue,mn,"ø","\\o",!0),we(si,Ue,mn,"Æ","\\AE",!0),we(si,Ue,mn,"Œ","\\OE",!0),we(si,Ue,mn,"Ø","\\O",!0),we(si,Ue,wh,"ˊ","\\'"),we(si,Ue,wh,"ˋ","\\`"),we(si,Ue,wh,"ˆ","\\^"),we(si,Ue,wh,"˜","\\~"),we(si,Ue,wh,"ˉ","\\="),we(si,Ue,wh,"˘","\\u"),we(si,Ue,wh,"˙","\\."),we(si,Ue,wh,"¸","\\c"),we(si,Ue,wh,"˚","\\r"),we(si,Ue,wh,"ˇ","\\v"),we(si,Ue,wh,"¨",'\\"'),we(si,Ue,wh,"˝","\\H"),we(si,Ue,wh,"◯","\\textcircled");var rze={"--":!0,"---":!0,"``":!0,"''":!0};we(si,Ue,mn,"–","--",!0),we(si,Ue,mn,"–","\\textendash"),we(si,Ue,mn,"—","---",!0),we(si,Ue,mn,"—","\\textemdash"),we(si,Ue,mn,"‘","`",!0),we(si,Ue,mn,"‘","\\textquoteleft"),we(si,Ue,mn,"’","'",!0),we(si,Ue,mn,"’","\\textquoteright"),we(si,Ue,mn,"“","``",!0),we(si,Ue,mn,"“","\\textquotedblleft"),we(si,Ue,mn,"”","''",!0),we(si,Ue,mn,"”","\\textquotedblright"),we(Ae,Ue,mn,"°","\\degree",!0),we(si,Ue,mn,"°","\\degree"),we(si,Ue,mn,"°","\\textdegree",!0),we(Ae,Ue,mn,"£","\\pounds"),we(Ae,Ue,mn,"£","\\mathsterling",!0),we(si,Ue,mn,"£","\\pounds"),we(si,Ue,mn,"£","\\textsterling",!0),we(Ae,$t,mn,"✠","\\maltese"),we(si,$t,mn,"✠","\\maltese");for(var ize='0123456789/@."',rbe=0;rbe0)return F3(v,_,p,u,b.concat(A));if(T){var P,R;if(T==="boldsymbol"){var F=mHt(v,p,u,b,d);P=F.fontName,R=[F.fontClass]}else y?(P=hze[T].fontName,R=[T]):(P=dQ(T,u.fontWeight,u.fontShape),R=[T,u.fontWeight,u.fontShape]);if(fQ(v,P,p).metrics)return F3(v,P,p,u,b.concat(R));if(rze.hasOwnProperty(v)&&P.slice(0,10)==="Typewriter"){for(var j=[],K=0;K{if(T9(i.classes)!==T9(s.classes)||i.skew!==s.skew||i.maxFontSize!==s.maxFontSize)return!1;if(i.classes.length===1){var u=i.classes[0];if(u==="mbin"||u==="mord")return!1}for(var d in i.style)if(i.style.hasOwnProperty(d)&&i.style[d]!==s.style[d])return!1;for(var p in s.style)if(s.style.hasOwnProperty(p)&&i.style[p]!==s.style[p])return!1;return!0},yHt=i=>{for(var s=0;su&&(u=b.height),b.depth>d&&(d=b.depth),b.maxFontSize>p&&(p=b.maxFontSize)}s.height=u,s.depth=d,s.maxFontSize=p},R2=function(s,u,d,p){var v=new cR(s,u,d,p);return cbe(v),v},uze=(i,s,u,d)=>new cR(i,s,u,d),xHt=function(s,u,d){var p=R2([s],[],u);return p.height=Math.max(d||u.fontMetrics().defaultRuleThickness,u.minRuleThickness),p.style.borderBottomWidth=Ri(p.height),p.maxFontSize=1,p},kHt=function(s,u,d,p){var v=new tbe(s,u,d,p);return cbe(v),v},lze=function(s){var u=new oR(s);return cbe(u),u},EHt=function(s,u){return s instanceof oR?R2([],[s],u):s},THt=function(s){if(s.positionType==="individualShift"){for(var u=s.children,d=[u[0]],p=-u[0].shift-u[0].elem.depth,v=p,b=1;b{var u=R2(["mspace"],[],s),d=Uh(i,s);return u.style.marginRight=Ri(d),u},dQ=function(s,u,d){var p="";switch(s){case"amsrm":p="AMS";break;case"textrm":p="Main";break;case"textsf":p="SansSerif";break;case"texttt":p="Typewriter";break;default:p=s}var v;return u==="textbf"&&d==="textit"?v="BoldItalic":u==="textbf"?v="Bold":u==="textit"?v="Italic":v="Regular",p+"-"+v},hze={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"}},fze={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},_Ht=function(s,u){var[d,p,v]=fze[s],b=new C9(d),y=new D7([b],{width:Ri(p),height:Ri(v),style:"width:"+Ri(p),viewBox:"0 0 "+1e3*p+" "+1e3*v,preserveAspectRatio:"xMinYMin"}),T=uze(["overlay"],[y],u);return T.height=v,T.style.height=Ri(v),T.style.width=Ri(p),T},zn={fontMap:hze,makeSymbol:F3,mathsym:bHt,makeSpan:R2,makeSvgSpan:uze,makeLineSpan:xHt,makeAnchor:kHt,makeFragment:lze,wrapFragment:EHt,makeVList:CHt,makeOrd:vHt,makeGlue:SHt,staticSvg:_Ht,svgData:fze,tryCombineChars:yHt},Gh={number:3,unit:"mu"},$C={number:4,unit:"mu"},O7={number:5,unit:"mu"},AHt={mord:{mop:Gh,mbin:$C,mrel:O7,minner:Gh},mop:{mord:Gh,mop:Gh,mrel:O7,minner:Gh},mbin:{mord:$C,mop:$C,mopen:$C,minner:$C},mrel:{mord:O7,mop:O7,mopen:O7,minner:O7},mopen:{},mclose:{mop:Gh,mbin:$C,mrel:O7,minner:Gh},mpunct:{mord:Gh,mop:Gh,mrel:O7,mopen:Gh,mclose:Gh,mpunct:Gh,minner:Gh},minner:{mord:Gh,mop:Gh,mbin:$C,mrel:O7,mopen:Gh,mpunct:Gh,minner:Gh}},LHt={mord:{mop:Gh},mop:{mord:Gh,mop:Gh},mbin:{},mrel:{},mopen:{},mclose:{mop:Gh},mpunct:{},minner:{mop:Gh}},dze={},gQ={},pQ={};function Ji(i){for(var{type:s,names:u,props:d,handler:p,htmlBuilder:v,mathmlBuilder:b}=i,y={type:s,numArgs:d.numArgs,argTypes:d.argTypes,allowedInArgument:!!d.allowedInArgument,allowedInText:!!d.allowedInText,allowedInMath:d.allowedInMath===void 0?!0:d.allowedInMath,numOptionalArgs:d.numOptionalArgs||0,infix:!!d.infix,primitive:!!d.primitive,handler:p},T=0;T{var ee=K.classes[0],ie=j.classes[0];ee==="mbin"&&Ya.contains(DHt,ie)?K.classes[0]="mord":ie==="mbin"&&Ya.contains(MHt,ee)&&(j.classes[0]="mord")},{node:P},R,F),gze(v,(j,K)=>{var ee=ube(K),ie=ube(j),oe=ee&&ie?j.hasClass("mtight")?LHt[ee][ie]:AHt[ee][ie]:null;if(oe)return zn.makeGlue(oe,_)},{node:P},R,F),v},gze=function i(s,u,d,p,v){p&&s.push(p);for(var b=0;bR=>{s.splice(P+1,0,R),b++})(b)}p&&s.pop()},pze=function(s){return s instanceof oR||s instanceof tbe||s instanceof cR&&s.hasClass("enclosing")?s:null},NHt=function i(s,u){var d=pze(s);if(d){var p=d.children;if(p.length){if(u==="right")return i(p[p.length-1],"right");if(u==="left")return i(p[0],"left")}}return s},ube=function(s,u){return s?(u&&(s=NHt(s,u)),OHt[s.classes[0]]||null):null},uR=function(s,u){var d=["nulldelimiter"].concat(s.baseSizingClasses());return N7(u.concat(d))},uu=function(s,u,d){if(!s)return N7();if(gQ[s.type]){var p=gQ[s.type](s,u);if(d&&u.size!==d.size){p=N7(u.sizingClasses(d),[p],u);var v=u.sizeMultiplier/d.sizeMultiplier;p.height*=v,p.depth*=v}return p}else throw new Ci("Got group of unknown type: '"+s.type+"'")};function mQ(i,s){var u=N7(["base"],i,s),d=N7(["strut"]);return d.style.height=Ri(u.height+u.depth),u.depth&&(d.style.verticalAlign=Ri(-u.depth)),u.children.unshift(d),u}function lbe(i,s){var u=null;i.length===1&&i[0].type==="tag"&&(u=i[0].tag,i=i[0].body);var d=d1(i,s,"root"),p;d.length===2&&d[1].hasClass("tag")&&(p=d.pop());for(var v=[],b=[],y=0;y0&&(v.push(mQ(b,s)),b=[]),v.push(d[y]));b.length>0&&v.push(mQ(b,s));var _;u?(_=mQ(d1(u,s,!0)),_.classes=["tag"],v.push(_)):p&&v.push(p);var A=N7(["katex-html"],v);if(A.setAttribute("aria-hidden","true"),_){var P=_.children[0];P.style.height=Ri(A.height+A.depth),A.depth&&(P.style.verticalAlign=Ri(-A.depth))}return A}function bze(i){return new oR(i)}class Fv{constructor(s,u,d){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=s,this.attributes={},this.children=u||[],this.classes=d||[]}setAttribute(s,u){this.attributes[s]=u}getAttribute(s){return this.attributes[s]}toNode(){var s=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var u in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,u)&&s.setAttribute(u,this.attributes[u]);this.classes.length>0&&(s.className=T9(this.classes));for(var d=0;d0&&(s+=' class ="'+Ya.escape(T9(this.classes))+'"'),s+=">";for(var d=0;d",s}toText(){return this.children.map(s=>s.toText()).join("")}}class lR{constructor(s){this.text=void 0,this.text=s}toNode(){return document.createTextNode(this.text)}toMarkup(){return Ya.escape(this.toText())}toText(){return this.text}}class PHt{constructor(s){this.width=void 0,this.character=void 0,this.width=s,s>=.05555&&s<=.05556?this.character=" ":s>=.1666&&s<=.1667?this.character=" ":s>=.2222&&s<=.2223?this.character=" ":s>=.2777&&s<=.2778?this.character="  ":s>=-.05556&&s<=-.05555?this.character=" ⁣":s>=-.1667&&s<=-.1666?this.character=" ⁣":s>=-.2223&&s<=-.2222?this.character=" ⁣":s>=-.2778&&s<=-.2777?this.character=" ⁣":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var s=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return s.setAttribute("width",Ri(this.width)),s}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}}var vi={MathNode:Fv,TextNode:lR,SpaceNode:PHt,newDocumentFragment:bze},Rv=function(s,u,d){return Ul[u][s]&&Ul[u][s].replace&&s.charCodeAt(0)!==55349&&!(rze.hasOwnProperty(s)&&d&&(d.fontFamily&&d.fontFamily.slice(4,6)==="tt"||d.font&&d.font.slice(4,6)==="tt"))&&(s=Ul[u][s].replace),new vi.TextNode(s)},hbe=function(s){return s.length===1?s[0]:new vi.MathNode("mrow",s)},fbe=function(s,u){if(u.fontFamily==="texttt")return"monospace";if(u.fontFamily==="textsf")return u.fontShape==="textit"&&u.fontWeight==="textbf"?"sans-serif-bold-italic":u.fontShape==="textit"?"sans-serif-italic":u.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(u.fontShape==="textit"&&u.fontWeight==="textbf")return"bold-italic";if(u.fontShape==="textit")return"italic";if(u.fontWeight==="textbf")return"bold";var d=u.font;if(!d||d==="mathnormal")return null;var p=s.mode;if(d==="mathit")return"italic";if(d==="boldsymbol")return s.type==="textord"?"bold":"bold-italic";if(d==="mathbf")return"bold";if(d==="mathbb")return"double-struck";if(d==="mathfrak")return"fraktur";if(d==="mathscr"||d==="mathcal")return"script";if(d==="mathsf")return"sans-serif";if(d==="mathtt")return"monospace";var v=s.text;if(Ya.contains(["\\imath","\\jmath"],v))return null;Ul[p][v]&&Ul[p][v].replace&&(v=Ul[p][v].replace);var b=zn.fontMap[d].fontName;return J2e(v,b,p)?zn.fontMap[d].variant:null},j2=function(s,u,d){if(s.length===1){var p=Ll(s[0],u);return d&&p instanceof Fv&&p.type==="mo"&&(p.setAttribute("lspace","0em"),p.setAttribute("rspace","0em")),[p]}for(var v=[],b,y=0;y0&&(P.text=P.text.slice(0,1)+"̸"+P.text.slice(1),v.pop())}}}v.push(T),b=T}return v},_9=function(s,u,d){return hbe(j2(s,u,d))},Ll=function(s,u){if(!s)return new vi.MathNode("mrow");if(pQ[s.type]){var d=pQ[s.type](s,u);return d}else throw new Ci("Got group of unknown type: '"+s.type+"'")};function mze(i,s,u,d,p){var v=j2(i,u),b;v.length===1&&v[0]instanceof Fv&&Ya.contains(["mrow","mtable"],v[0].type)?b=v[0]:b=new vi.MathNode("mrow",v);var y=new vi.MathNode("annotation",[new vi.TextNode(s)]);y.setAttribute("encoding","application/x-tex");var T=new vi.MathNode("semantics",[b,y]),_=new vi.MathNode("math",[T]);_.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),d&&_.setAttribute("display","block");var A=p?"katex":"katex-mathml";return zn.makeSpan([A],[_])}var vze=function(s){return new M7({style:s.displayMode?Ta.DISPLAY:Ta.TEXT,maxSize:s.maxSize,minRuleThickness:s.minRuleThickness})},wze=function(s,u){if(u.displayMode){var d=["katex-display"];u.leqno&&d.push("leqno"),u.fleqn&&d.push("fleqn"),s=zn.makeSpan(d,[s])}return s},BHt=function(s,u,d){var p=vze(d),v;if(d.output==="mathml")return mze(s,u,p,d.displayMode,!0);if(d.output==="html"){var b=lbe(s,p);v=zn.makeSpan(["katex"],[b])}else{var y=mze(s,u,p,d.displayMode,!1),T=lbe(s,p);v=zn.makeSpan(["katex"],[y,T])}return wze(v,d)},FHt=function(s,u,d){var p=vze(d),v=lbe(s,p),b=zn.makeSpan(["katex"],[v]);return wze(b,d)},RHt={widehat:"^",widecheck:"ˇ",widetilde:"~",utilde:"~",overleftarrow:"←",underleftarrow:"←",xleftarrow:"←",overrightarrow:"→",underrightarrow:"→",xrightarrow:"→",underbrace:"⏟",overbrace:"⏞",overgroup:"⏠",undergroup:"⏡",overleftrightarrow:"↔",underleftrightarrow:"↔",xleftrightarrow:"↔",Overrightarrow:"⇒",xRightarrow:"⇒",overleftharpoon:"↼",xleftharpoonup:"↼",overrightharpoon:"⇀",xrightharpoonup:"⇀",xLeftarrow:"⇐",xLeftrightarrow:"⇔",xhookleftarrow:"↩",xhookrightarrow:"↪",xmapsto:"↦",xrightharpoondown:"⇁",xleftharpoondown:"↽",xrightleftharpoons:"⇌",xleftrightharpoons:"⇋",xtwoheadleftarrow:"↞",xtwoheadrightarrow:"↠",xlongequal:"=",xtofrom:"⇄",xrightleftarrows:"⇄",xrightequilibrium:"⇌",xleftequilibrium:"⇋","\\cdrightarrow":"→","\\cdleftarrow":"←","\\cdlongequal":"="},jHt=function(s){var u=new vi.MathNode("mo",[new vi.TextNode(RHt[s.replace(/^\\/,"")])]);return u.setAttribute("stretchy","true"),u},$Ht={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]},zHt=function(s){return s.type==="ordgroup"?s.body.length:1},qHt=function(s,u){function d(){var y=4e5,T=s.label.slice(1);if(Ya.contains(["widehat","widecheck","widetilde","utilde"],T)){var _=s,A=zHt(_.base),P,R,F;if(A>5)T==="widehat"||T==="widecheck"?(P=420,y=2364,F=.42,R=T+"4"):(P=312,y=2340,F=.34,R="tilde4");else{var j=[1,1,2,2,3,3][A];T==="widehat"||T==="widecheck"?(y=[0,1062,2364,2364,2364][j],P=[0,239,300,360,420][j],F=[0,.24,.3,.3,.36,.42][j],R=T+j):(y=[0,600,1033,2339,2340][j],P=[0,260,286,306,312][j],F=[0,.26,.286,.3,.306,.34][j],R="tilde"+j)}var K=new C9(R),ee=new D7([K],{width:"100%",height:Ri(F),viewBox:"0 0 "+y+" "+P,preserveAspectRatio:"none"});return{span:zn.makeSvgSpan([],[ee],u),minWidth:0,height:F}}else{var ie=[],oe=$Ht[T],[pe,be,ae]=oe,ne=ae/1e3,se=pe.length,de,X;if(se===1){var ge=oe[3];de=["hide-tail"],X=[ge]}else if(se===2)de=["halfarrow-left","halfarrow-right"],X=["xMinYMin","xMaxYMin"];else if(se===3)de=["brace-left","brace-center","brace-right"],X=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support + `+se+" children.");for(var W=0;W0&&(p.style.minWidth=Ri(v)),p},HHt=function(s,u,d,p,v){var b,y=s.height+s.depth+d+p;if(/fbox|color|angl/.test(u)){if(b=zn.makeSpan(["stretchy",u],[],v),u==="fbox"){var T=v.color&&v.getColor();T&&(b.style.borderColor=T)}}else{var _=[];/^[bx]cancel$/.test(u)&&_.push(new nbe({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(u)&&_.push(new nbe({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var A=new D7(_,{width:"100%",height:Ri(y)});b=zn.makeSvgSpan([],[A],v)}return b.height=y,b.style.height=Ri(y),b},P7={encloseSpan:HHt,mathMLnode:jHt,svgSpan:qHt};function Yo(i,s){if(!i||i.type!==s)throw new Error("Expected node of type "+s+", but got "+(i?"node of type "+i.type:String(i)));return i}function dbe(i){var s=vQ(i);if(!s)throw new Error("Expected node of symbol group type, but got "+(i?"node of type "+i.type:String(i)));return s}function vQ(i){return i&&(i.type==="atom"||gHt.hasOwnProperty(i.type))?i:null}var gbe=(i,s)=>{var u,d,p;i&&i.type==="supsub"?(d=Yo(i.base,"accent"),u=d.base,i.base=u,p=fHt(uu(i,s)),i.base=d):(d=Yo(i,"accent"),u=d.base);var v=uu(u,s.havingCrampedStyle()),b=d.isShifty&&Ya.isCharacterBox(u),y=0;if(b){var T=Ya.getBaseElem(u),_=uu(T,s.havingCrampedStyle());y=nze(_).skew}var A=d.label==="\\c",P=A?v.height+v.depth:Math.min(v.height,s.fontMetrics().xHeight),R;if(d.isStretchy)R=P7.svgSpan(d,s),R=zn.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:v},{type:"elem",elem:R,wrapperClasses:["svg-align"],wrapperStyle:y>0?{width:"calc(100% - "+Ri(2*y)+")",marginLeft:Ri(2*y)}:void 0}]},s);else{var F,j;d.label==="\\vec"?(F=zn.staticSvg("vec",s),j=zn.svgData.vec[1]):(F=zn.makeOrd({mode:d.mode,text:d.label},s,"textord"),F=nze(F),F.italic=0,j=F.width,A&&(P+=F.depth)),R=zn.makeSpan(["accent-body"],[F]);var K=d.label==="\\textcircled";K&&(R.classes.push("accent-full"),P=v.height);var ee=y;K||(ee-=j/2),R.style.left=Ri(ee),d.label==="\\textcircled"&&(R.style.top=".2em"),R=zn.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:v},{type:"kern",size:-P},{type:"elem",elem:R}]},s)}var ie=zn.makeSpan(["mord","accent"],[R],s);return p?(p.children[0]=ie,p.height=Math.max(ie.height,p.height),p.classes[0]="mord",p):ie},yze=(i,s)=>{var u=i.isStretchy?P7.mathMLnode(i.label):new vi.MathNode("mo",[Rv(i.label,i.mode)]),d=new vi.MathNode("mover",[Ll(i.base,s),u]);return d.setAttribute("accent","true"),d},VHt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(i=>"\\"+i).join("|"));Ji({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:(i,s)=>{var u=bQ(s[0]),d=!VHt.test(i.funcName),p=!d||i.funcName==="\\widehat"||i.funcName==="\\widetilde"||i.funcName==="\\widecheck";return{type:"accent",mode:i.parser.mode,label:i.funcName,isStretchy:d,isShifty:p,base:u}},htmlBuilder:gbe,mathmlBuilder:yze}),Ji({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(i,s)=>{var u=s[0],d=i.parser.mode;return d==="math"&&(i.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+i.funcName+" works only in text mode"),d="text"),{type:"accent",mode:d,label:i.funcName,isStretchy:!1,isShifty:!0,base:u}},htmlBuilder:gbe,mathmlBuilder:yze}),Ji({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=s[0];return{type:"accentUnder",mode:u.mode,label:d,base:p}},htmlBuilder:(i,s)=>{var u=uu(i.base,s),d=P7.svgSpan(i,s),p=i.label==="\\utilde"?.12:0,v=zn.makeVList({positionType:"top",positionData:u.height,children:[{type:"elem",elem:d,wrapperClasses:["svg-align"]},{type:"kern",size:p},{type:"elem",elem:u}]},s);return zn.makeSpan(["mord","accentunder"],[v],s)},mathmlBuilder:(i,s)=>{var u=P7.mathMLnode(i.label),d=new vi.MathNode("munder",[Ll(i.base,s),u]);return d.setAttribute("accentunder","true"),d}});var wQ=i=>{var s=new vi.MathNode("mpadded",i?[i]:[]);return s.setAttribute("width","+0.6em"),s.setAttribute("lspace","0.3em"),s};Ji({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(i,s,u){var{parser:d,funcName:p}=i;return{type:"xArrow",mode:d.mode,label:p,body:s[0],below:u[0]}},htmlBuilder(i,s){var u=s.style,d=s.havingStyle(u.sup()),p=zn.wrapFragment(uu(i.body,d,s),s),v=i.label.slice(0,2)==="\\x"?"x":"cd";p.classes.push(v+"-arrow-pad");var b;i.below&&(d=s.havingStyle(u.sub()),b=zn.wrapFragment(uu(i.below,d,s),s),b.classes.push(v+"-arrow-pad"));var y=P7.svgSpan(i,s),T=-s.fontMetrics().axisHeight+.5*y.height,_=-s.fontMetrics().axisHeight-.5*y.height-.111;(p.depth>.25||i.label==="\\xleftequilibrium")&&(_-=p.depth);var A;if(b){var P=-s.fontMetrics().axisHeight+b.height+.5*y.height+.111;A=zn.makeVList({positionType:"individualShift",children:[{type:"elem",elem:p,shift:_},{type:"elem",elem:y,shift:T},{type:"elem",elem:b,shift:P}]},s)}else A=zn.makeVList({positionType:"individualShift",children:[{type:"elem",elem:p,shift:_},{type:"elem",elem:y,shift:T}]},s);return A.children[0].children[0].children[1].classes.push("svg-align"),zn.makeSpan(["mrel","x-arrow"],[A],s)},mathmlBuilder(i,s){var u=P7.mathMLnode(i.label);u.setAttribute("minsize",i.label.charAt(0)==="x"?"1.75em":"3.0em");var d;if(i.body){var p=wQ(Ll(i.body,s));if(i.below){var v=wQ(Ll(i.below,s));d=new vi.MathNode("munderover",[u,v,p])}else d=new vi.MathNode("mover",[u,p])}else if(i.below){var b=wQ(Ll(i.below,s));d=new vi.MathNode("munder",[u,b])}else d=wQ(),d=new vi.MathNode("mover",[u,d]);return d}});var UHt=zn.makeSpan;function xze(i,s){var u=d1(i.body,s,!0);return UHt([i.mclass],u,s)}function kze(i,s){var u,d=j2(i.body,s);return i.mclass==="minner"?u=new vi.MathNode("mpadded",d):i.mclass==="mord"?i.isCharacterBox?(u=d[0],u.type="mi"):u=new vi.MathNode("mi",d):(i.isCharacterBox?(u=d[0],u.type="mo"):u=new vi.MathNode("mo",d),i.mclass==="mbin"?(u.attributes.lspace="0.22em",u.attributes.rspace="0.22em"):i.mclass==="mpunct"?(u.attributes.lspace="0em",u.attributes.rspace="0.17em"):i.mclass==="mopen"||i.mclass==="mclose"?(u.attributes.lspace="0em",u.attributes.rspace="0em"):i.mclass==="minner"&&(u.attributes.lspace="0.0556em",u.attributes.width="+0.1111em")),u}Ji({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(i,s){var{parser:u,funcName:d}=i,p=s[0];return{type:"mclass",mode:u.mode,mclass:"m"+d.slice(5),body:Xf(p),isCharacterBox:Ya.isCharacterBox(p)}},htmlBuilder:xze,mathmlBuilder:kze});var yQ=i=>{var s=i.type==="ordgroup"&&i.body.length?i.body[0]:i;return s.type==="atom"&&(s.family==="bin"||s.family==="rel")?"m"+s.family:"mord"};Ji({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(i,s){var{parser:u}=i;return{type:"mclass",mode:u.mode,mclass:yQ(s[0]),body:Xf(s[1]),isCharacterBox:Ya.isCharacterBox(s[1])}}}),Ji({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(i,s){var{parser:u,funcName:d}=i,p=s[1],v=s[0],b;d!=="\\stackrel"?b=yQ(p):b="mrel";var y={type:"op",mode:p.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:d!=="\\stackrel",body:Xf(p)},T={type:"supsub",mode:v.mode,base:y,sup:d==="\\underset"?null:v,sub:d==="\\underset"?v:null};return{type:"mclass",mode:u.mode,mclass:b,body:[T],isCharacterBox:Ya.isCharacterBox(T)}},htmlBuilder:xze,mathmlBuilder:kze}),Ji({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(i,s){var{parser:u}=i;return{type:"pmb",mode:u.mode,mclass:yQ(s[0]),body:Xf(s[0])}},htmlBuilder(i,s){var u=d1(i.body,s,!0),d=zn.makeSpan([i.mclass],u,s);return d.style.textShadow="0.02em 0.01em 0.04px",d},mathmlBuilder(i,s){var u=j2(i.body,s),d=new vi.MathNode("mstyle",u);return d.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),d}});var GHt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},Eze=()=>({type:"styling",body:[],mode:"math",style:"display"}),Tze=i=>i.type==="textord"&&i.text==="@",KHt=(i,s)=>(i.type==="mathord"||i.type==="atom")&&i.text===s;function WHt(i,s,u){var d=GHt[i];switch(d){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return u.callFunction(d,[s[0]],[s[1]]);case"\\uparrow":case"\\downarrow":{var p=u.callFunction("\\\\cdleft",[s[0]],[]),v={type:"atom",text:d,mode:"math",family:"rel"},b=u.callFunction("\\Big",[v],[]),y=u.callFunction("\\\\cdright",[s[1]],[]),T={type:"ordgroup",mode:"math",body:[p,b,y]};return u.callFunction("\\\\cdparent",[T],[])}case"\\\\cdlongequal":return u.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var _={type:"textord",text:"\\Vert",mode:"math"};return u.callFunction("\\Big",[_],[])}default:return{type:"textord",text:" ",mode:"math"}}}function YHt(i){var s=[];for(i.gullet.beginGroup(),i.gullet.macros.set("\\cr","\\\\\\relax"),i.gullet.beginGroup();;){s.push(i.parseExpression(!1,"\\\\")),i.gullet.endGroup(),i.gullet.beginGroup();var u=i.fetch().text;if(u==="&"||u==="\\\\")i.consume();else if(u==="\\end"){s[s.length-1].length===0&&s.pop();break}else throw new Ci("Expected \\\\ or \\cr or \\end",i.nextToken)}for(var d=[],p=[d],v=0;v-1))if("<>AV".indexOf(_)>-1)for(var P=0;P<2;P++){for(var R=!0,F=T+1;FAV=|." after @',b[T]);var j=WHt(_,A,i),K={type:"styling",body:[j],mode:"math",style:"display"};d.push(K),y=Eze()}v%2===0?d.push(y):d.shift(),d=[],p.push(d)}i.gullet.endGroup(),i.gullet.endGroup();var ee=new Array(p[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:p,arraystretch:1,addJot:!0,rowGaps:[null],cols:ee,colSeparationType:"CD",hLinesBeforeRow:new Array(p.length+1).fill([])}}Ji({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(i,s){var{parser:u,funcName:d}=i;return{type:"cdlabel",mode:u.mode,side:d.slice(4),label:s[0]}},htmlBuilder(i,s){var u=s.havingStyle(s.style.sup()),d=zn.wrapFragment(uu(i.label,u,s),s);return d.classes.push("cd-label-"+i.side),d.style.bottom=Ri(.8-d.depth),d.height=0,d.depth=0,d},mathmlBuilder(i,s){var u=new vi.MathNode("mrow",[Ll(i.label,s)]);return u=new vi.MathNode("mpadded",[u]),u.setAttribute("width","0"),i.side==="left"&&u.setAttribute("lspace","-1width"),u.setAttribute("voffset","0.7em"),u=new vi.MathNode("mstyle",[u]),u.setAttribute("displaystyle","false"),u.setAttribute("scriptlevel","1"),u}}),Ji({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(i,s){var{parser:u}=i;return{type:"cdlabelparent",mode:u.mode,fragment:s[0]}},htmlBuilder(i,s){var u=zn.wrapFragment(uu(i.fragment,s),s);return u.classes.push("cd-vert-arrow"),u},mathmlBuilder(i,s){return new vi.MathNode("mrow",[Ll(i.fragment,s)])}}),Ji({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(i,s){for(var{parser:u}=i,d=Yo(s[0],"ordgroup"),p=d.body,v="",b=0;b=1114111)throw new Ci("\\@char with invalid code point "+v);return T<=65535?_=String.fromCharCode(T):(T-=65536,_=String.fromCharCode((T>>10)+55296,(T&1023)+56320)),{type:"textord",mode:u.mode,text:_}}});var Cze=(i,s)=>{var u=d1(i.body,s.withColor(i.color),!1);return zn.makeFragment(u)},Sze=(i,s)=>{var u=j2(i.body,s.withColor(i.color)),d=new vi.MathNode("mstyle",u);return d.setAttribute("mathcolor",i.color),d};Ji({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(i,s){var{parser:u}=i,d=Yo(s[0],"color-token").color,p=s[1];return{type:"color",mode:u.mode,color:d,body:Xf(p)}},htmlBuilder:Cze,mathmlBuilder:Sze}),Ji({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(i,s){var{parser:u,breakOnTokenText:d}=i,p=Yo(s[0],"color-token").color;u.gullet.macros.set("\\current@color",p);var v=u.parseExpression(!0,d);return{type:"color",mode:u.mode,color:p,body:v}},htmlBuilder:Cze,mathmlBuilder:Sze}),Ji({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(i,s,u){var{parser:d}=i,p=d.gullet.future().text==="["?d.parseSizeGroup(!0):null,v=!d.settings.displayMode||!d.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:d.mode,newLine:v,size:p&&Yo(p,"size").value}},htmlBuilder(i,s){var u=zn.makeSpan(["mspace"],[],s);return i.newLine&&(u.classes.push("newline"),i.size&&(u.style.marginTop=Ri(Uh(i.size,s)))),u},mathmlBuilder(i,s){var u=new vi.MathNode("mspace");return i.newLine&&(u.setAttribute("linebreak","newline"),i.size&&u.setAttribute("height",Ri(Uh(i.size,s)))),u}});var pbe={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},_ze=i=>{var s=i.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(s))throw new Ci("Expected a control sequence",i);return s},XHt=i=>{var s=i.gullet.popToken();return s.text==="="&&(s=i.gullet.popToken(),s.text===" "&&(s=i.gullet.popToken())),s},Aze=(i,s,u,d)=>{var p=i.gullet.macros.get(u.text);p==null&&(u.noexpand=!0,p={tokens:[u],numArgs:0,unexpandable:!i.gullet.isExpandable(u.text)}),i.gullet.macros.set(s,p,d)};Ji({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(i){var{parser:s,funcName:u}=i;s.consumeSpaces();var d=s.fetch();if(pbe[d.text])return(u==="\\global"||u==="\\\\globallong")&&(d.text=pbe[d.text]),Yo(s.parseFunction(),"internal");throw new Ci("Invalid token after macro prefix",d)}}),Ji({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:s,funcName:u}=i,d=s.gullet.popToken(),p=d.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(p))throw new Ci("Expected a control sequence",d);for(var v=0,b,y=[[]];s.gullet.future().text!=="{";)if(d=s.gullet.popToken(),d.text==="#"){if(s.gullet.future().text==="{"){b=s.gullet.future(),y[v].push("{");break}if(d=s.gullet.popToken(),!/^[1-9]$/.test(d.text))throw new Ci('Invalid argument number "'+d.text+'"');if(parseInt(d.text)!==v+1)throw new Ci('Argument number "'+d.text+'" out of order');v++,y.push([])}else{if(d.text==="EOF")throw new Ci("Expected a macro definition");y[v].push(d.text)}var{tokens:T}=s.gullet.consumeArg();return b&&T.unshift(b),(u==="\\edef"||u==="\\xdef")&&(T=s.gullet.expandTokens(T),T.reverse()),s.gullet.macros.set(p,{tokens:T,numArgs:v,delimiters:y},u===pbe[u]),{type:"internal",mode:s.mode}}}),Ji({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:s,funcName:u}=i,d=_ze(s.gullet.popToken());s.gullet.consumeSpaces();var p=XHt(s);return Aze(s,d,p,u==="\\\\globallet"),{type:"internal",mode:s.mode}}}),Ji({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:s,funcName:u}=i,d=_ze(s.gullet.popToken()),p=s.gullet.popToken(),v=s.gullet.popToken();return Aze(s,d,v,u==="\\\\globalfuture"),s.gullet.pushToken(v),s.gullet.pushToken(p),{type:"internal",mode:s.mode}}});var hR=function(s,u,d){var p=Ul.math[s]&&Ul.math[s].replace,v=J2e(p||s,u,d);if(!v)throw new Error("Unsupported symbol "+s+" and font size "+u+".");return v},bbe=function(s,u,d,p){var v=d.havingBaseStyle(u),b=zn.makeSpan(p.concat(v.sizingClasses(d)),[s],d),y=v.sizeMultiplier/d.sizeMultiplier;return b.height*=y,b.depth*=y,b.maxFontSize=v.sizeMultiplier,b},Lze=function(s,u,d){var p=u.havingBaseStyle(d),v=(1-u.sizeMultiplier/p.sizeMultiplier)*u.fontMetrics().axisHeight;s.classes.push("delimcenter"),s.style.top=Ri(v),s.height-=v,s.depth+=v},QHt=function(s,u,d,p,v,b){var y=zn.makeSymbol(s,"Main-Regular",v,p),T=bbe(y,u,p,b);return d&&Lze(T,p,u),T},JHt=function(s,u,d,p){return zn.makeSymbol(s,"Size"+u+"-Regular",d,p)},Mze=function(s,u,d,p,v,b){var y=JHt(s,u,v,p),T=bbe(zn.makeSpan(["delimsizing","size"+u],[y],p),Ta.TEXT,p,b);return d&&Lze(T,p,Ta.TEXT),T},mbe=function(s,u,d){var p;u==="Size1-Regular"?p="delim-size1":p="delim-size4";var v=zn.makeSpan(["delimsizinginner",p],[zn.makeSpan([],[zn.makeSymbol(s,u,d)])]);return{type:"elem",elem:v}},vbe=function(s,u,d){var p=K4["Size4-Regular"][s.charCodeAt(0)]?K4["Size4-Regular"][s.charCodeAt(0)][4]:K4["Size1-Regular"][s.charCodeAt(0)][4],v=new C9("inner",iHt(s,Math.round(1e3*u))),b=new D7([v],{width:Ri(p),height:Ri(u),style:"width:"+Ri(p),viewBox:"0 0 "+1e3*p+" "+Math.round(1e3*u),preserveAspectRatio:"xMinYMin"}),y=zn.makeSvgSpan([],[b],d);return y.height=u,y.style.height=Ri(u),y.style.width=Ri(p),{type:"elem",elem:y}},wbe=.008,xQ={type:"kern",size:-1*wbe},ZHt=["|","\\lvert","\\rvert","\\vert"],eVt=["\\|","\\lVert","\\rVert","\\Vert"],Dze=function(s,u,d,p,v,b){var y,T,_,A,P="",R=0;y=_=A=s,T=null;var F="Size1-Regular";s==="\\uparrow"?_=A="⏐":s==="\\Uparrow"?_=A="‖":s==="\\downarrow"?y=_="⏐":s==="\\Downarrow"?y=_="‖":s==="\\updownarrow"?(y="\\uparrow",_="⏐",A="\\downarrow"):s==="\\Updownarrow"?(y="\\Uparrow",_="‖",A="\\Downarrow"):Ya.contains(ZHt,s)?(_="∣",P="vert",R=333):Ya.contains(eVt,s)?(_="∥",P="doublevert",R=556):s==="["||s==="\\lbrack"?(y="⎡",_="⎢",A="⎣",F="Size4-Regular",P="lbrack",R=667):s==="]"||s==="\\rbrack"?(y="⎤",_="⎥",A="⎦",F="Size4-Regular",P="rbrack",R=667):s==="\\lfloor"||s==="⌊"?(_=y="⎢",A="⎣",F="Size4-Regular",P="lfloor",R=667):s==="\\lceil"||s==="⌈"?(y="⎡",_=A="⎢",F="Size4-Regular",P="lceil",R=667):s==="\\rfloor"||s==="⌋"?(_=y="⎥",A="⎦",F="Size4-Regular",P="rfloor",R=667):s==="\\rceil"||s==="⌉"?(y="⎤",_=A="⎥",F="Size4-Regular",P="rceil",R=667):s==="("||s==="\\lparen"?(y="⎛",_="⎜",A="⎝",F="Size4-Regular",P="lparen",R=875):s===")"||s==="\\rparen"?(y="⎞",_="⎟",A="⎠",F="Size4-Regular",P="rparen",R=875):s==="\\{"||s==="\\lbrace"?(y="⎧",T="⎨",A="⎩",_="⎪",F="Size4-Regular"):s==="\\}"||s==="\\rbrace"?(y="⎫",T="⎬",A="⎭",_="⎪",F="Size4-Regular"):s==="\\lgroup"||s==="⟮"?(y="⎧",A="⎩",_="⎪",F="Size4-Regular"):s==="\\rgroup"||s==="⟯"?(y="⎫",A="⎭",_="⎪",F="Size4-Regular"):s==="\\lmoustache"||s==="⎰"?(y="⎧",A="⎭",_="⎪",F="Size4-Regular"):(s==="\\rmoustache"||s==="⎱")&&(y="⎫",A="⎩",_="⎪",F="Size4-Regular");var j=hR(y,F,v),K=j.height+j.depth,ee=hR(_,F,v),ie=ee.height+ee.depth,oe=hR(A,F,v),pe=oe.height+oe.depth,be=0,ae=1;if(T!==null){var ne=hR(T,F,v);be=ne.height+ne.depth,ae=2}var se=K+pe+be,de=Math.max(0,Math.ceil((u-se)/(ae*ie))),X=se+de*ae*ie,ge=p.fontMetrics().axisHeight;d&&(ge*=p.sizeMultiplier);var W=X/2-ge,xe=[];if(P.length>0){var U=X-K-pe,Fe=Math.round(X*1e3),Pe=sHt(P,Math.round(U*1e3)),je=new C9(P,Pe),Ie=(R/1e3).toFixed(3)+"em",Se=(Fe/1e3).toFixed(3)+"em",Ce=new D7([je],{width:Ie,height:Se,viewBox:"0 0 "+R+" "+Fe}),ke=zn.makeSvgSpan([],[Ce],p);ke.height=Fe/1e3,ke.style.width=Ie,ke.style.height=Se,xe.push({type:"elem",elem:ke})}else{if(xe.push(mbe(A,F,v)),xe.push(xQ),T===null){var Ke=X-K-pe+2*wbe;xe.push(vbe(_,Ke,p))}else{var Ft=(X-K-pe-be)/2+2*wbe;xe.push(vbe(_,Ft,p)),xe.push(xQ),xe.push(mbe(T,F,v)),xe.push(xQ),xe.push(vbe(_,Ft,p))}xe.push(xQ),xe.push(mbe(y,F,v))}var Ne=p.havingBaseStyle(Ta.TEXT),gn=zn.makeVList({positionType:"bottom",positionData:W,children:xe},Ne);return bbe(zn.makeSpan(["delimsizing","mult"],[gn],Ne),Ta.TEXT,p,b)},ybe=80,xbe=.08,kbe=function(s,u,d,p,v){var b=rHt(s,p,d),y=new C9(s,b),T=new D7([y],{width:"400em",height:Ri(u),viewBox:"0 0 400000 "+d,preserveAspectRatio:"xMinYMin slice"});return zn.makeSvgSpan(["hide-tail"],[T],v)},tVt=function(s,u){var d=u.havingBaseSizing(),p=Pze("\\surd",s*d.sizeMultiplier,Nze,d),v=d.sizeMultiplier,b=Math.max(0,u.minRuleThickness-u.fontMetrics().sqrtRuleThickness),y,T=0,_=0,A=0,P;return p.type==="small"?(A=1e3+1e3*b+ybe,s<1?v=1:s<1.4&&(v=.7),T=(1+b+xbe)/v,_=(1+b)/v,y=kbe("sqrtMain",T,A,b,u),y.style.minWidth="0.853em",P=.833/v):p.type==="large"?(A=(1e3+ybe)*fR[p.size],_=(fR[p.size]+b)/v,T=(fR[p.size]+b+xbe)/v,y=kbe("sqrtSize"+p.size,T,A,b,u),y.style.minWidth="1.02em",P=1/v):(T=s+b+xbe,_=s+b,A=Math.floor(1e3*s+b)+ybe,y=kbe("sqrtTall",T,A,b,u),y.style.minWidth="0.742em",P=1.056),y.height=_,y.style.height=Ri(T),{span:y,advanceWidth:P,ruleWidth:(u.fontMetrics().sqrtRuleThickness+b)*v}},Ize=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","\\surd"],nVt=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱"],Oze=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],fR=[0,1.2,1.8,2.4,3],rVt=function(s,u,d,p,v){if(s==="<"||s==="\\lt"||s==="⟨"?s="\\langle":(s===">"||s==="\\gt"||s==="⟩")&&(s="\\rangle"),Ya.contains(Ize,s)||Ya.contains(Oze,s))return Mze(s,u,!1,d,p,v);if(Ya.contains(nVt,s))return Dze(s,fR[u],!1,d,p,v);throw new Ci("Illegal delimiter: '"+s+"'")},iVt=[{type:"small",style:Ta.SCRIPTSCRIPT},{type:"small",style:Ta.SCRIPT},{type:"small",style:Ta.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],sVt=[{type:"small",style:Ta.SCRIPTSCRIPT},{type:"small",style:Ta.SCRIPT},{type:"small",style:Ta.TEXT},{type:"stack"}],Nze=[{type:"small",style:Ta.SCRIPTSCRIPT},{type:"small",style:Ta.SCRIPT},{type:"small",style:Ta.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],aVt=function(s){if(s.type==="small")return"Main-Regular";if(s.type==="large")return"Size"+s.size+"-Regular";if(s.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+s.type+"' here.")},Pze=function(s,u,d,p){for(var v=Math.min(2,3-p.style.size),b=v;bu)return d[b]}return d[d.length-1]},Bze=function(s,u,d,p,v,b){s==="<"||s==="\\lt"||s==="⟨"?s="\\langle":(s===">"||s==="\\gt"||s==="⟩")&&(s="\\rangle");var y;Ya.contains(Oze,s)?y=iVt:Ya.contains(Ize,s)?y=Nze:y=sVt;var T=Pze(s,u,y,p);return T.type==="small"?QHt(s,T.style,d,p,v,b):T.type==="large"?Mze(s,T.size,d,p,v,b):Dze(s,u,d,p,v,b)},oVt=function(s,u,d,p,v,b){var y=p.fontMetrics().axisHeight*p.sizeMultiplier,T=901,_=5/p.fontMetrics().ptPerEm,A=Math.max(u-y,d+y),P=Math.max(A/500*T,2*A-_);return Bze(s,P,!0,p,v,b)},B7={sqrtImage:tVt,sizedDelim:rVt,sizeToMaxHeight:fR,customSizedDelim:Bze,leftRightDelim:oVt},Fze={"\\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}},cVt=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","<",">","\\langle","⟨","\\rangle","⟩","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function kQ(i,s){var u=vQ(i);if(u&&Ya.contains(cVt,u.text))return u;throw u?new Ci("Invalid delimiter '"+u.text+"' after '"+s.funcName+"'",i):new Ci("Invalid delimiter type '"+i.type+"'",i)}Ji({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:(i,s)=>{var u=kQ(s[0],i);return{type:"delimsizing",mode:i.parser.mode,size:Fze[i.funcName].size,mclass:Fze[i.funcName].mclass,delim:u.text}},htmlBuilder:(i,s)=>i.delim==="."?zn.makeSpan([i.mclass]):B7.sizedDelim(i.delim,i.size,s,i.mode,[i.mclass]),mathmlBuilder:i=>{var s=[];i.delim!=="."&&s.push(Rv(i.delim,i.mode));var u=new vi.MathNode("mo",s);i.mclass==="mopen"||i.mclass==="mclose"?u.setAttribute("fence","true"):u.setAttribute("fence","false"),u.setAttribute("stretchy","true");var d=Ri(B7.sizeToMaxHeight[i.size]);return u.setAttribute("minsize",d),u.setAttribute("maxsize",d),u}});function Rze(i){if(!i.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}Ji({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(i,s)=>{var u=i.parser.gullet.macros.get("\\current@color");if(u&&typeof u!="string")throw new Ci("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:i.parser.mode,delim:kQ(s[0],i).text,color:u}}}),Ji({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(i,s)=>{var u=kQ(s[0],i),d=i.parser;++d.leftrightDepth;var p=d.parseExpression(!1);--d.leftrightDepth,d.expect("\\right",!1);var v=Yo(d.parseFunction(),"leftright-right");return{type:"leftright",mode:d.mode,body:p,left:u.text,right:v.delim,rightColor:v.color}},htmlBuilder:(i,s)=>{Rze(i);for(var u=d1(i.body,s,!0,["mopen","mclose"]),d=0,p=0,v=!1,b=0;b{Rze(i);var u=j2(i.body,s);if(i.left!=="."){var d=new vi.MathNode("mo",[Rv(i.left,i.mode)]);d.setAttribute("fence","true"),u.unshift(d)}if(i.right!=="."){var p=new vi.MathNode("mo",[Rv(i.right,i.mode)]);p.setAttribute("fence","true"),i.rightColor&&p.setAttribute("mathcolor",i.rightColor),u.push(p)}return hbe(u)}}),Ji({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(i,s)=>{var u=kQ(s[0],i);if(!i.parser.leftrightDepth)throw new Ci("\\middle without preceding \\left",u);return{type:"middle",mode:i.parser.mode,delim:u.text}},htmlBuilder:(i,s)=>{var u;if(i.delim===".")u=uR(s,[]);else{u=B7.sizedDelim(i.delim,1,s,i.mode,[]);var d={delim:i.delim,options:s};u.isMiddle=d}return u},mathmlBuilder:(i,s)=>{var u=i.delim==="\\vert"||i.delim==="|"?Rv("|","text"):Rv(i.delim,i.mode),d=new vi.MathNode("mo",[u]);return d.setAttribute("fence","true"),d.setAttribute("lspace","0.05em"),d.setAttribute("rspace","0.05em"),d}});var Ebe=(i,s)=>{var u=zn.wrapFragment(uu(i.body,s),s),d=i.label.slice(1),p=s.sizeMultiplier,v,b=0,y=Ya.isCharacterBox(i.body);if(d==="sout")v=zn.makeSpan(["stretchy","sout"]),v.height=s.fontMetrics().defaultRuleThickness/p,b=-.5*s.fontMetrics().xHeight;else if(d==="phase"){var T=Uh({number:.6,unit:"pt"},s),_=Uh({number:.35,unit:"ex"},s),A=s.havingBaseSizing();p=p/A.sizeMultiplier;var P=u.height+u.depth+T+_;u.style.paddingLeft=Ri(P/2+T);var R=Math.floor(1e3*P*p),F=tHt(R),j=new D7([new C9("phase",F)],{width:"400em",height:Ri(R/1e3),viewBox:"0 0 400000 "+R,preserveAspectRatio:"xMinYMin slice"});v=zn.makeSvgSpan(["hide-tail"],[j],s),v.style.height=Ri(P),b=u.depth+T+_}else{/cancel/.test(d)?y||u.classes.push("cancel-pad"):d==="angl"?u.classes.push("anglpad"):u.classes.push("boxpad");var K=0,ee=0,ie=0;/box/.test(d)?(ie=Math.max(s.fontMetrics().fboxrule,s.minRuleThickness),K=s.fontMetrics().fboxsep+(d==="colorbox"?0:ie),ee=K):d==="angl"?(ie=Math.max(s.fontMetrics().defaultRuleThickness,s.minRuleThickness),K=4*ie,ee=Math.max(0,.25-u.depth)):(K=y?.2:0,ee=K),v=P7.encloseSpan(u,d,K,ee,s),/fbox|boxed|fcolorbox/.test(d)?(v.style.borderStyle="solid",v.style.borderWidth=Ri(ie)):d==="angl"&&ie!==.049&&(v.style.borderTopWidth=Ri(ie),v.style.borderRightWidth=Ri(ie)),b=u.depth+ee,i.backgroundColor&&(v.style.backgroundColor=i.backgroundColor,i.borderColor&&(v.style.borderColor=i.borderColor))}var oe;if(i.backgroundColor)oe=zn.makeVList({positionType:"individualShift",children:[{type:"elem",elem:v,shift:b},{type:"elem",elem:u,shift:0}]},s);else{var pe=/cancel|phase/.test(d)?["svg-align"]:[];oe=zn.makeVList({positionType:"individualShift",children:[{type:"elem",elem:u,shift:0},{type:"elem",elem:v,shift:b,wrapperClasses:pe}]},s)}return/cancel/.test(d)&&(oe.height=u.height,oe.depth=u.depth),/cancel/.test(d)&&!y?zn.makeSpan(["mord","cancel-lap"],[oe],s):zn.makeSpan(["mord"],[oe],s)},Tbe=(i,s)=>{var u=0,d=new vi.MathNode(i.label.indexOf("colorbox")>-1?"mpadded":"menclose",[Ll(i.body,s)]);switch(i.label){case"\\cancel":d.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":d.setAttribute("notation","downdiagonalstrike");break;case"\\phase":d.setAttribute("notation","phasorangle");break;case"\\sout":d.setAttribute("notation","horizontalstrike");break;case"\\fbox":d.setAttribute("notation","box");break;case"\\angl":d.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(u=s.fontMetrics().fboxsep*s.fontMetrics().ptPerEm,d.setAttribute("width","+"+2*u+"pt"),d.setAttribute("height","+"+2*u+"pt"),d.setAttribute("lspace",u+"pt"),d.setAttribute("voffset",u+"pt"),i.label==="\\fcolorbox"){var p=Math.max(s.fontMetrics().fboxrule,s.minRuleThickness);d.setAttribute("style","border: "+p+"em solid "+String(i.borderColor))}break;case"\\xcancel":d.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return i.backgroundColor&&d.setAttribute("mathbackground",i.backgroundColor),d};Ji({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(i,s,u){var{parser:d,funcName:p}=i,v=Yo(s[0],"color-token").color,b=s[1];return{type:"enclose",mode:d.mode,label:p,backgroundColor:v,body:b}},htmlBuilder:Ebe,mathmlBuilder:Tbe}),Ji({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(i,s,u){var{parser:d,funcName:p}=i,v=Yo(s[0],"color-token").color,b=Yo(s[1],"color-token").color,y=s[2];return{type:"enclose",mode:d.mode,label:p,backgroundColor:b,borderColor:v,body:y}},htmlBuilder:Ebe,mathmlBuilder:Tbe}),Ji({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(i,s){var{parser:u}=i;return{type:"enclose",mode:u.mode,label:"\\fbox",body:s[0]}}}),Ji({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(i,s){var{parser:u,funcName:d}=i,p=s[0];return{type:"enclose",mode:u.mode,label:d,body:p}},htmlBuilder:Ebe,mathmlBuilder:Tbe}),Ji({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(i,s){var{parser:u}=i;return{type:"enclose",mode:u.mode,label:"\\angl",body:s[0]}}});var jze={};function W4(i){for(var{type:s,names:u,props:d,handler:p,htmlBuilder:v,mathmlBuilder:b}=i,y={type:s,numArgs:d.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:p},T=0;T{var s=i.parser.settings;if(!s.displayMode)throw new Ci("{"+i.envName+"} can be used only in display mode.")};function Cbe(i){if(i.indexOf("ed")===-1)return i.indexOf("*")===-1}function A9(i,s,u){var{hskipBeforeAndAfter:d,addJot:p,cols:v,arraystretch:b,colSeparationType:y,autoTag:T,singleRow:_,emptySingleRow:A,maxNumCols:P,leqno:R}=s;if(i.gullet.beginGroup(),_||i.gullet.macros.set("\\cr","\\\\\\relax"),!b){var F=i.gullet.expandMacroAsText("\\arraystretch");if(F==null)b=1;else if(b=parseFloat(F),!b||b<0)throw new Ci("Invalid \\arraystretch: "+F)}i.gullet.beginGroup();var j=[],K=[j],ee=[],ie=[],oe=T!=null?[]:void 0;function pe(){T&&i.gullet.macros.set("\\@eqnsw","1",!0)}function be(){oe&&(i.gullet.macros.get("\\df@tag")?(oe.push(i.subparse([new U4("\\df@tag")])),i.gullet.macros.set("\\df@tag",void 0,!0)):oe.push(!!T&&i.gullet.macros.get("\\@eqnsw")==="1"))}for(pe(),ie.push(zze(i));;){var ae=i.parseExpression(!1,_?"\\end":"\\\\");i.gullet.endGroup(),i.gullet.beginGroup(),ae={type:"ordgroup",mode:i.mode,body:ae},u&&(ae={type:"styling",mode:i.mode,style:u,body:[ae]}),j.push(ae);var ne=i.fetch().text;if(ne==="&"){if(P&&j.length===P){if(_||y)throw new Ci("Too many tab characters: &",i.nextToken);i.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}i.consume()}else if(ne==="\\end"){be(),j.length===1&&ae.type==="styling"&&ae.body[0].body.length===0&&(K.length>1||!A)&&K.pop(),ie.length0&&(pe+=.25),_.push({pos:pe,isDashed:ji[xi]})}for(be(b[0]),d=0;d0&&(W+=oe,seji))for(d=0;d=y)){var Gt=void 0;(p>0||s.hskipBeforeAndAfter)&&(Gt=Ya.deflt(Ft.pregap,R),Gt!==0&&(Pe=zn.makeSpan(["arraycolsep"],[]),Pe.style.width=Ri(Gt),Fe.push(Pe)));var ln=[];for(d=0;d0){for(var Dt=zn.makeLineSpan("hline",u,A),kt=zn.makeLineSpan("hdashline",u,A),On=[{type:"elem",elem:T,shift:0}];_.length>0;){var ht=_.pop(),zr=ht.pos-xe;ht.isDashed?On.push({type:"elem",elem:kt,shift:zr}):On.push({type:"elem",elem:Dt,shift:zr})}T=zn.makeVList({positionType:"individualShift",children:On},u)}if(Ie.length===0)return zn.makeSpan(["mord"],[T],u);var yt=zn.makeVList({positionType:"individualShift",children:Ie},u);return yt=zn.makeSpan(["tag"],[yt],u),zn.makeFragment([T,yt])},uVt={c:"center ",l:"left ",r:"right "},X4=function(s,u){for(var d=[],p=new vi.MathNode("mtd",[],["mtr-glue"]),v=new vi.MathNode("mtd",[],["mml-eqn-num"]),b=0;b0){var j=s.cols,K="",ee=!1,ie=0,oe=j.length;j[0].type==="separator"&&(R+="top ",ie=1),j[j.length-1].type==="separator"&&(R+="bottom ",oe-=1);for(var pe=ie;pe0?"left ":"",R+=de[de.length-1].length>0?"right ":"";for(var X=1;X-1?"alignat":"align",v=s.envName==="split",b=A9(s.parser,{cols:d,addJot:!0,autoTag:v?void 0:Cbe(s.envName),emptySingleRow:!0,colSeparationType:p,maxNumCols:v?2:void 0,leqno:s.parser.settings.leqno},"display"),y,T=0,_={type:"ordgroup",mode:s.mode,body:[]};if(u[0]&&u[0].type==="ordgroup"){for(var A="",P=0;P0&&F&&(ee=1),d[j]={type:"align",align:K,pregap:ee,postgap:0}}return b.colSeparationType=F?"align":"alignat",b};W4({type:"array",names:["array","darray"],props:{numArgs:1},handler(i,s){var u=vQ(s[0]),d=u?[s[0]]:Yo(s[0],"ordgroup").body,p=d.map(function(b){var y=dbe(b),T=y.text;if("lcr".indexOf(T)!==-1)return{type:"align",align:T};if(T==="|")return{type:"separator",separator:"|"};if(T===":")return{type:"separator",separator:":"};throw new Ci("Unknown column alignment: "+T,b)}),v={cols:p,hskipBeforeAndAfter:!0,maxNumCols:p.length};return A9(i.parser,v,Sbe(i.envName))},htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(i){var s={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[i.envName.replace("*","")],u="c",d={hskipBeforeAndAfter:!1,cols:[{type:"align",align:u}]};if(i.envName.charAt(i.envName.length-1)==="*"){var p=i.parser;if(p.consumeSpaces(),p.fetch().text==="["){if(p.consume(),p.consumeSpaces(),u=p.fetch().text,"lcr".indexOf(u)===-1)throw new Ci("Expected l or c or r",p.nextToken);p.consume(),p.consumeSpaces(),p.expect("]"),p.consume(),d.cols=[{type:"align",align:u}]}}var v=A9(i.parser,d,Sbe(i.envName)),b=Math.max(0,...v.body.map(y=>y.length));return v.cols=new Array(b).fill({type:"align",align:u}),s?{type:"leftright",mode:i.mode,body:[v],left:s[0],right:s[1],rightColor:void 0}:v},htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(i){var s={arraystretch:.5},u=A9(i.parser,s,"script");return u.colSeparationType="small",u},htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["subarray"],props:{numArgs:1},handler(i,s){var u=vQ(s[0]),d=u?[s[0]]:Yo(s[0],"ordgroup").body,p=d.map(function(b){var y=dbe(b),T=y.text;if("lc".indexOf(T)!==-1)return{type:"align",align:T};throw new Ci("Unknown column alignment: "+T,b)});if(p.length>1)throw new Ci("{subarray} can contain only one column");var v={cols:p,hskipBeforeAndAfter:!1,arraystretch:.5};if(v=A9(i.parser,v,"script"),v.body.length>0&&v.body[0].length>1)throw new Ci("{subarray} can contain only one column");return v},htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(i){var s={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},u=A9(i.parser,s,Sbe(i.envName));return{type:"leftright",mode:i.mode,body:[u],left:i.envName.indexOf("r")>-1?".":"\\{",right:i.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:qze,htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(i){Ya.contains(["gather","gather*"],i.envName)&&EQ(i);var s={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Cbe(i.envName),emptySingleRow:!0,leqno:i.parser.settings.leqno};return A9(i.parser,s,"display")},htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:qze,htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(i){EQ(i);var s={autoTag:Cbe(i.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:i.parser.settings.leqno};return A9(i.parser,s,"display")},htmlBuilder:Y4,mathmlBuilder:X4}),W4({type:"array",names:["CD"],props:{numArgs:0},handler(i){return EQ(i),YHt(i.parser)},htmlBuilder:Y4,mathmlBuilder:X4}),et("\\nonumber","\\gdef\\@eqnsw{0}"),et("\\notag","\\nonumber"),Ji({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(i,s){throw new Ci(i.funcName+" valid only within array environment")}});var Hze=jze;Ji({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(i,s){var{parser:u,funcName:d}=i,p=s[0];if(p.type!=="ordgroup")throw new Ci("Invalid environment name",p);for(var v="",b=0;b{var u=i.font,d=s.withFont(u);return uu(i.body,d)},Uze=(i,s)=>{var u=i.font,d=s.withFont(u);return Ll(i.body,d)},Gze={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};Ji({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=bQ(s[0]),v=d;return v in Gze&&(v=Gze[v]),{type:"font",mode:u.mode,font:v.slice(1),body:p}},htmlBuilder:Vze,mathmlBuilder:Uze}),Ji({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(i,s)=>{var{parser:u}=i,d=s[0],p=Ya.isCharacterBox(d);return{type:"mclass",mode:u.mode,mclass:yQ(d),body:[{type:"font",mode:u.mode,font:"boldsymbol",body:d}],isCharacterBox:p}}}),Ji({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(i,s)=>{var{parser:u,funcName:d,breakOnTokenText:p}=i,{mode:v}=u,b=u.parseExpression(!0,p),y="math"+d.slice(1);return{type:"font",mode:v,font:y,body:{type:"ordgroup",mode:u.mode,body:b}}},htmlBuilder:Vze,mathmlBuilder:Uze});var Kze=(i,s)=>{var u=s;return i==="display"?u=u.id>=Ta.SCRIPT.id?u.text():Ta.DISPLAY:i==="text"&&u.size===Ta.DISPLAY.size?u=Ta.TEXT:i==="script"?u=Ta.SCRIPT:i==="scriptscript"&&(u=Ta.SCRIPTSCRIPT),u},_be=(i,s)=>{var u=Kze(i.size,s.style),d=u.fracNum(),p=u.fracDen(),v;v=s.havingStyle(d);var b=uu(i.numer,v,s);if(i.continued){var y=8.5/s.fontMetrics().ptPerEm,T=3.5/s.fontMetrics().ptPerEm;b.height=b.height0?j=3*R:j=7*R,K=s.fontMetrics().denom1):(P>0?(F=s.fontMetrics().num2,j=R):(F=s.fontMetrics().num3,j=3*R),K=s.fontMetrics().denom2);var ee;if(A){var oe=s.fontMetrics().axisHeight;F-b.depth-(oe+.5*P){var u=new vi.MathNode("mfrac",[Ll(i.numer,s),Ll(i.denom,s)]);if(!i.hasBarLine)u.setAttribute("linethickness","0px");else if(i.barSize){var d=Uh(i.barSize,s);u.setAttribute("linethickness",Ri(d))}var p=Kze(i.size,s.style);if(p.size!==s.style.size){u=new vi.MathNode("mstyle",[u]);var v=p.size===Ta.DISPLAY.size?"true":"false";u.setAttribute("displaystyle",v),u.setAttribute("scriptlevel","0")}if(i.leftDelim!=null||i.rightDelim!=null){var b=[];if(i.leftDelim!=null){var y=new vi.MathNode("mo",[new vi.TextNode(i.leftDelim.replace("\\",""))]);y.setAttribute("fence","true"),b.push(y)}if(b.push(u),i.rightDelim!=null){var T=new vi.MathNode("mo",[new vi.TextNode(i.rightDelim.replace("\\",""))]);T.setAttribute("fence","true"),b.push(T)}return hbe(b)}return u};Ji({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=s[0],v=s[1],b,y=null,T=null,_="auto";switch(d){case"\\dfrac":case"\\frac":case"\\tfrac":b=!0;break;case"\\\\atopfrac":b=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":b=!1,y="(",T=")";break;case"\\\\bracefrac":b=!1,y="\\{",T="\\}";break;case"\\\\brackfrac":b=!1,y="[",T="]";break;default:throw new Error("Unrecognized genfrac command")}switch(d){case"\\dfrac":case"\\dbinom":_="display";break;case"\\tfrac":case"\\tbinom":_="text";break}return{type:"genfrac",mode:u.mode,continued:!1,numer:p,denom:v,hasBarLine:b,leftDelim:y,rightDelim:T,size:_,barSize:null}},htmlBuilder:_be,mathmlBuilder:Abe}),Ji({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=s[0],v=s[1];return{type:"genfrac",mode:u.mode,continued:!0,numer:p,denom:v,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),Ji({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(i){var{parser:s,funcName:u,token:d}=i,p;switch(u){case"\\over":p="\\frac";break;case"\\choose":p="\\binom";break;case"\\atop":p="\\\\atopfrac";break;case"\\brace":p="\\\\bracefrac";break;case"\\brack":p="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:s.mode,replaceWith:p,token:d}}});var Wze=["display","text","script","scriptscript"],Yze=function(s){var u=null;return s.length>0&&(u=s,u=u==="."?null:u),u};Ji({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(i,s){var{parser:u}=i,d=s[4],p=s[5],v=bQ(s[0]),b=v.type==="atom"&&v.family==="open"?Yze(v.text):null,y=bQ(s[1]),T=y.type==="atom"&&y.family==="close"?Yze(y.text):null,_=Yo(s[2],"size"),A,P=null;_.isBlank?A=!0:(P=_.value,A=P.number>0);var R="auto",F=s[3];if(F.type==="ordgroup"){if(F.body.length>0){var j=Yo(F.body[0],"textord");R=Wze[Number(j.text)]}}else F=Yo(F,"textord"),R=Wze[Number(F.text)];return{type:"genfrac",mode:u.mode,numer:d,denom:p,continued:!1,hasBarLine:A,barSize:P,leftDelim:b,rightDelim:T,size:R}},htmlBuilder:_be,mathmlBuilder:Abe}),Ji({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(i,s){var{parser:u,funcName:d,token:p}=i;return{type:"infix",mode:u.mode,replaceWith:"\\\\abovefrac",size:Yo(s[0],"size").value,token:p}}}),Ji({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=s[0],v=$qt(Yo(s[1],"infix").size),b=s[2],y=v.number>0;return{type:"genfrac",mode:u.mode,numer:p,denom:b,continued:!1,hasBarLine:y,barSize:v,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:_be,mathmlBuilder:Abe});var Xze=(i,s)=>{var u=s.style,d,p;i.type==="supsub"?(d=i.sup?uu(i.sup,s.havingStyle(u.sup()),s):uu(i.sub,s.havingStyle(u.sub()),s),p=Yo(i.base,"horizBrace")):p=Yo(i,"horizBrace");var v=uu(p.base,s.havingBaseStyle(Ta.DISPLAY)),b=P7.svgSpan(p,s),y;if(p.isOver?(y=zn.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:v},{type:"kern",size:.1},{type:"elem",elem:b}]},s),y.children[0].children[0].children[1].classes.push("svg-align")):(y=zn.makeVList({positionType:"bottom",positionData:v.depth+.1+b.height,children:[{type:"elem",elem:b},{type:"kern",size:.1},{type:"elem",elem:v}]},s),y.children[0].children[0].children[0].classes.push("svg-align")),d){var T=zn.makeSpan(["mord",p.isOver?"mover":"munder"],[y],s);p.isOver?y=zn.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:T},{type:"kern",size:.2},{type:"elem",elem:d}]},s):y=zn.makeVList({positionType:"bottom",positionData:T.depth+.2+d.height+d.depth,children:[{type:"elem",elem:d},{type:"kern",size:.2},{type:"elem",elem:T}]},s)}return zn.makeSpan(["mord",p.isOver?"mover":"munder"],[y],s)},lVt=(i,s)=>{var u=P7.mathMLnode(i.label);return new vi.MathNode(i.isOver?"mover":"munder",[Ll(i.base,s),u])};Ji({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(i,s){var{parser:u,funcName:d}=i;return{type:"horizBrace",mode:u.mode,label:d,isOver:/^\\over/.test(d),base:s[0]}},htmlBuilder:Xze,mathmlBuilder:lVt}),Ji({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(i,s)=>{var{parser:u}=i,d=s[1],p=Yo(s[0],"url").url;return u.settings.isTrusted({command:"\\href",url:p})?{type:"href",mode:u.mode,href:p,body:Xf(d)}:u.formatUnsupportedCmd("\\href")},htmlBuilder:(i,s)=>{var u=d1(i.body,s,!1);return zn.makeAnchor(i.href,[],u,s)},mathmlBuilder:(i,s)=>{var u=_9(i.body,s);return u instanceof Fv||(u=new Fv("mrow",[u])),u.setAttribute("href",i.href),u}}),Ji({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(i,s)=>{var{parser:u}=i,d=Yo(s[0],"url").url;if(!u.settings.isTrusted({command:"\\url",url:d}))return u.formatUnsupportedCmd("\\url");for(var p=[],v=0;v{var{parser:u,funcName:d,token:p}=i,v=Yo(s[0],"raw").string,b=s[1];u.settings.strict&&u.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var y,T={};switch(d){case"\\htmlClass":T.class=v,y={command:"\\htmlClass",class:v};break;case"\\htmlId":T.id=v,y={command:"\\htmlId",id:v};break;case"\\htmlStyle":T.style=v,y={command:"\\htmlStyle",style:v};break;case"\\htmlData":{for(var _=v.split(","),A=0;A<_.length;A++){var P=_[A].split("=");if(P.length!==2)throw new Ci("Error parsing key-value for \\htmlData");T["data-"+P[0].trim()]=P[1].trim()}y={command:"\\htmlData",attributes:T};break}default:throw new Error("Unrecognized html command")}return u.settings.isTrusted(y)?{type:"html",mode:u.mode,attributes:T,body:Xf(b)}:u.formatUnsupportedCmd(d)},htmlBuilder:(i,s)=>{var u=d1(i.body,s,!1),d=["enclosing"];i.attributes.class&&d.push(...i.attributes.class.trim().split(/\s+/));var p=zn.makeSpan(d,u,s);for(var v in i.attributes)v!=="class"&&i.attributes.hasOwnProperty(v)&&p.setAttribute(v,i.attributes[v]);return p},mathmlBuilder:(i,s)=>_9(i.body,s)}),Ji({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(i,s)=>{var{parser:u}=i;return{type:"htmlmathml",mode:u.mode,html:Xf(s[0]),mathml:Xf(s[1])}},htmlBuilder:(i,s)=>{var u=d1(i.html,s,!1);return zn.makeFragment(u)},mathmlBuilder:(i,s)=>_9(i.mathml,s)});var Lbe=function(s){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(s))return{number:+s,unit:"bp"};var u=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(s);if(!u)throw new Ci("Invalid size: '"+s+"' in \\includegraphics");var d={number:+(u[1]+u[2]),unit:u[3]};if(!J$e(d))throw new Ci("Invalid unit: '"+d.unit+"' in \\includegraphics.");return d};Ji({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(i,s,u)=>{var{parser:d}=i,p={number:0,unit:"em"},v={number:.9,unit:"em"},b={number:0,unit:"em"},y="";if(u[0])for(var T=Yo(u[0],"raw").string,_=T.split(","),A=0;A<_.length;A++){var P=_[A].split("=");if(P.length===2){var R=P[1].trim();switch(P[0].trim()){case"alt":y=R;break;case"width":p=Lbe(R);break;case"height":v=Lbe(R);break;case"totalheight":b=Lbe(R);break;default:throw new Ci("Invalid key: '"+P[0]+"' in \\includegraphics.")}}}var F=Yo(s[0],"url").url;return y===""&&(y=F,y=y.replace(/^.*[\\/]/,""),y=y.substring(0,y.lastIndexOf("."))),d.settings.isTrusted({command:"\\includegraphics",url:F})?{type:"includegraphics",mode:d.mode,alt:y,width:p,height:v,totalheight:b,src:F}:d.formatUnsupportedCmd("\\includegraphics")},htmlBuilder:(i,s)=>{var u=Uh(i.height,s),d=0;i.totalheight.number>0&&(d=Uh(i.totalheight,s)-u);var p=0;i.width.number>0&&(p=Uh(i.width,s));var v={height:Ri(u+d)};p>0&&(v.width=Ri(p)),d>0&&(v.verticalAlign=Ri(-d));var b=new lHt(i.src,i.alt,v);return b.height=u,b.depth=d,b},mathmlBuilder:(i,s)=>{var u=new vi.MathNode("mglyph",[]);u.setAttribute("alt",i.alt);var d=Uh(i.height,s),p=0;if(i.totalheight.number>0&&(p=Uh(i.totalheight,s)-d,u.setAttribute("valign",Ri(-p))),u.setAttribute("height",Ri(d+p)),i.width.number>0){var v=Uh(i.width,s);u.setAttribute("width",Ri(v))}return u.setAttribute("src",i.src),u}}),Ji({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(i,s){var{parser:u,funcName:d}=i,p=Yo(s[0],"size");if(u.settings.strict){var v=d[1]==="m",b=p.value.unit==="mu";v?(b||u.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+d+" supports only mu units, "+("not "+p.value.unit+" units")),u.mode!=="math"&&u.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+d+" works only in math mode")):b&&u.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+d+" doesn't support mu units")}return{type:"kern",mode:u.mode,dimension:p.value}},htmlBuilder(i,s){return zn.makeGlue(i.dimension,s)},mathmlBuilder(i,s){var u=Uh(i.dimension,s);return new vi.SpaceNode(u)}}),Ji({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=s[0];return{type:"lap",mode:u.mode,alignment:d.slice(5),body:p}},htmlBuilder:(i,s)=>{var u;i.alignment==="clap"?(u=zn.makeSpan([],[uu(i.body,s)]),u=zn.makeSpan(["inner"],[u],s)):u=zn.makeSpan(["inner"],[uu(i.body,s)]);var d=zn.makeSpan(["fix"],[]),p=zn.makeSpan([i.alignment],[u,d],s),v=zn.makeSpan(["strut"]);return v.style.height=Ri(p.height+p.depth),p.depth&&(v.style.verticalAlign=Ri(-p.depth)),p.children.unshift(v),p=zn.makeSpan(["thinbox"],[p],s),zn.makeSpan(["mord","vbox"],[p],s)},mathmlBuilder:(i,s)=>{var u=new vi.MathNode("mpadded",[Ll(i.body,s)]);if(i.alignment!=="rlap"){var d=i.alignment==="llap"?"-1":"-0.5";u.setAttribute("lspace",d+"width")}return u.setAttribute("width","0px"),u}}),Ji({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(i,s){var{funcName:u,parser:d}=i,p=d.mode;d.switchMode("math");var v=u==="\\("?"\\)":"$",b=d.parseExpression(!1,v);return d.expect(v),d.switchMode(p),{type:"styling",mode:d.mode,style:"text",body:b}}}),Ji({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(i,s){throw new Ci("Mismatched "+i.funcName)}});var Qze=(i,s)=>{switch(s.style.size){case Ta.DISPLAY.size:return i.display;case Ta.TEXT.size:return i.text;case Ta.SCRIPT.size:return i.script;case Ta.SCRIPTSCRIPT.size:return i.scriptscript;default:return i.text}};Ji({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(i,s)=>{var{parser:u}=i;return{type:"mathchoice",mode:u.mode,display:Xf(s[0]),text:Xf(s[1]),script:Xf(s[2]),scriptscript:Xf(s[3])}},htmlBuilder:(i,s)=>{var u=Qze(i,s),d=d1(u,s,!1);return zn.makeFragment(d)},mathmlBuilder:(i,s)=>{var u=Qze(i,s);return _9(u,s)}});var Jze=(i,s,u,d,p,v,b)=>{i=zn.makeSpan([],[i]);var y=u&&Ya.isCharacterBox(u),T,_;if(s){var A=uu(s,d.havingStyle(p.sup()),d);_={elem:A,kern:Math.max(d.fontMetrics().bigOpSpacing1,d.fontMetrics().bigOpSpacing3-A.depth)}}if(u){var P=uu(u,d.havingStyle(p.sub()),d);T={elem:P,kern:Math.max(d.fontMetrics().bigOpSpacing2,d.fontMetrics().bigOpSpacing4-P.height)}}var R;if(_&&T){var F=d.fontMetrics().bigOpSpacing5+T.elem.height+T.elem.depth+T.kern+i.depth+b;R=zn.makeVList({positionType:"bottom",positionData:F,children:[{type:"kern",size:d.fontMetrics().bigOpSpacing5},{type:"elem",elem:T.elem,marginLeft:Ri(-v)},{type:"kern",size:T.kern},{type:"elem",elem:i},{type:"kern",size:_.kern},{type:"elem",elem:_.elem,marginLeft:Ri(v)},{type:"kern",size:d.fontMetrics().bigOpSpacing5}]},d)}else if(T){var j=i.height-b;R=zn.makeVList({positionType:"top",positionData:j,children:[{type:"kern",size:d.fontMetrics().bigOpSpacing5},{type:"elem",elem:T.elem,marginLeft:Ri(-v)},{type:"kern",size:T.kern},{type:"elem",elem:i}]},d)}else if(_){var K=i.depth+b;R=zn.makeVList({positionType:"bottom",positionData:K,children:[{type:"elem",elem:i},{type:"kern",size:_.kern},{type:"elem",elem:_.elem,marginLeft:Ri(v)},{type:"kern",size:d.fontMetrics().bigOpSpacing5}]},d)}else return i;var ee=[R];if(T&&v!==0&&!y){var ie=zn.makeSpan(["mspace"],[],d);ie.style.marginRight=Ri(v),ee.unshift(ie)}return zn.makeSpan(["mop","op-limits"],ee,d)},Zze=["\\smallint"],PD=(i,s)=>{var u,d,p=!1,v;i.type==="supsub"?(u=i.sup,d=i.sub,v=Yo(i.base,"op"),p=!0):v=Yo(i,"op");var b=s.style,y=!1;b.size===Ta.DISPLAY.size&&v.symbol&&!Ya.contains(Zze,v.name)&&(y=!0);var T;if(v.symbol){var _=y?"Size2-Regular":"Size1-Regular",A="";if((v.name==="\\oiint"||v.name==="\\oiiint")&&(A=v.name.slice(1),v.name=A==="oiint"?"\\iint":"\\iiint"),T=zn.makeSymbol(v.name,_,"math",s,["mop","op-symbol",y?"large-op":"small-op"]),A.length>0){var P=T.italic,R=zn.staticSvg(A+"Size"+(y?"2":"1"),s);T=zn.makeVList({positionType:"individualShift",children:[{type:"elem",elem:T,shift:0},{type:"elem",elem:R,shift:y?.08:0}]},s),v.name="\\"+A,T.classes.unshift("mop"),T.italic=P}}else if(v.body){var F=d1(v.body,s,!0);F.length===1&&F[0]instanceof Bv?(T=F[0],T.classes[0]="mop"):T=zn.makeSpan(["mop"],F,s)}else{for(var j=[],K=1;K{var u;if(i.symbol)u=new Fv("mo",[Rv(i.name,i.mode)]),Ya.contains(Zze,i.name)&&u.setAttribute("largeop","false");else if(i.body)u=new Fv("mo",j2(i.body,s));else{u=new Fv("mi",[new lR(i.name.slice(1))]);var d=new Fv("mo",[Rv("⁡","text")]);i.parentIsSupSub?u=new Fv("mrow",[u,d]):u=bze([u,d])}return u},hVt={"∏":"\\prod","∐":"\\coprod","∑":"\\sum","⋀":"\\bigwedge","⋁":"\\bigvee","⋂":"\\bigcap","⋃":"\\bigcup","⨀":"\\bigodot","⨁":"\\bigoplus","⨂":"\\bigotimes","⨄":"\\biguplus","⨆":"\\bigsqcup"};Ji({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","∏","∐","∑","⋀","⋁","⋂","⋃","⨀","⨁","⨂","⨄","⨆"],props:{numArgs:0},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=d;return p.length===1&&(p=hVt[p]),{type:"op",mode:u.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:p}},htmlBuilder:PD,mathmlBuilder:dR}),Ji({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(i,s)=>{var{parser:u}=i,d=s[0];return{type:"op",mode:u.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:Xf(d)}},htmlBuilder:PD,mathmlBuilder:dR});var fVt={"∫":"\\int","∬":"\\iint","∭":"\\iiint","∮":"\\oint","∯":"\\oiint","∰":"\\oiiint"};Ji({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(i){var{parser:s,funcName:u}=i;return{type:"op",mode:s.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:u}},htmlBuilder:PD,mathmlBuilder:dR}),Ji({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(i){var{parser:s,funcName:u}=i;return{type:"op",mode:s.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:u}},htmlBuilder:PD,mathmlBuilder:dR}),Ji({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","∫","∬","∭","∮","∯","∰"],props:{numArgs:0},handler(i){var{parser:s,funcName:u}=i,d=u;return d.length===1&&(d=fVt[d]),{type:"op",mode:s.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:d}},htmlBuilder:PD,mathmlBuilder:dR});var eqe=(i,s)=>{var u,d,p=!1,v;i.type==="supsub"?(u=i.sup,d=i.sub,v=Yo(i.base,"operatorname"),p=!0):v=Yo(i,"operatorname");var b;if(v.body.length>0){for(var y=v.body.map(P=>{var R=P.text;return typeof R=="string"?{type:"textord",mode:P.mode,text:R}:P}),T=d1(y,s.withFont("mathrm"),!0),_=0;_{for(var u=j2(i.body,s.withFont("mathrm")),d=!0,p=0;pA.toText()).join("");u=[new vi.TextNode(y)]}var T=new vi.MathNode("mi",u);T.setAttribute("mathvariant","normal");var _=new vi.MathNode("mo",[Rv("⁡","text")]);return i.parentIsSupSub?new vi.MathNode("mrow",[T,_]):vi.newDocumentFragment([T,_])};Ji({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:(i,s)=>{var{parser:u,funcName:d}=i,p=s[0];return{type:"operatorname",mode:u.mode,body:Xf(p),alwaysHandleSupSub:d==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},htmlBuilder:eqe,mathmlBuilder:dVt}),et("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@"),zC({type:"ordgroup",htmlBuilder(i,s){return i.semisimple?zn.makeFragment(d1(i.body,s,!1)):zn.makeSpan(["mord"],d1(i.body,s,!0),s)},mathmlBuilder(i,s){return _9(i.body,s,!0)}}),Ji({type:"overline",names:["\\overline"],props:{numArgs:1},handler(i,s){var{parser:u}=i,d=s[0];return{type:"overline",mode:u.mode,body:d}},htmlBuilder(i,s){var u=uu(i.body,s.havingCrampedStyle()),d=zn.makeLineSpan("overline-line",s),p=s.fontMetrics().defaultRuleThickness,v=zn.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:u},{type:"kern",size:3*p},{type:"elem",elem:d},{type:"kern",size:p}]},s);return zn.makeSpan(["mord","overline"],[v],s)},mathmlBuilder(i,s){var u=new vi.MathNode("mo",[new vi.TextNode("‾")]);u.setAttribute("stretchy","true");var d=new vi.MathNode("mover",[Ll(i.body,s),u]);return d.setAttribute("accent","true"),d}}),Ji({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(i,s)=>{var{parser:u}=i,d=s[0];return{type:"phantom",mode:u.mode,body:Xf(d)}},htmlBuilder:(i,s)=>{var u=d1(i.body,s.withPhantom(),!1);return zn.makeFragment(u)},mathmlBuilder:(i,s)=>{var u=j2(i.body,s);return new vi.MathNode("mphantom",u)}}),Ji({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(i,s)=>{var{parser:u}=i,d=s[0];return{type:"hphantom",mode:u.mode,body:d}},htmlBuilder:(i,s)=>{var u=zn.makeSpan([],[uu(i.body,s.withPhantom())]);if(u.height=0,u.depth=0,u.children)for(var d=0;d{var u=j2(Xf(i.body),s),d=new vi.MathNode("mphantom",u),p=new vi.MathNode("mpadded",[d]);return p.setAttribute("height","0px"),p.setAttribute("depth","0px"),p}}),Ji({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(i,s)=>{var{parser:u}=i,d=s[0];return{type:"vphantom",mode:u.mode,body:d}},htmlBuilder:(i,s)=>{var u=zn.makeSpan(["inner"],[uu(i.body,s.withPhantom())]),d=zn.makeSpan(["fix"],[]);return zn.makeSpan(["mord","rlap"],[u,d],s)},mathmlBuilder:(i,s)=>{var u=j2(Xf(i.body),s),d=new vi.MathNode("mphantom",u),p=new vi.MathNode("mpadded",[d]);return p.setAttribute("width","0px"),p}}),Ji({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(i,s){var{parser:u}=i,d=Yo(s[0],"size").value,p=s[1];return{type:"raisebox",mode:u.mode,dy:d,body:p}},htmlBuilder(i,s){var u=uu(i.body,s),d=Uh(i.dy,s);return zn.makeVList({positionType:"shift",positionData:-d,children:[{type:"elem",elem:u}]},s)},mathmlBuilder(i,s){var u=new vi.MathNode("mpadded",[Ll(i.body,s)]),d=i.dy.number+i.dy.unit;return u.setAttribute("voffset",d),u}}),Ji({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0},handler(i){var{parser:s}=i;return{type:"internal",mode:s.mode}}}),Ji({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,argTypes:["size","size","size"]},handler(i,s,u){var{parser:d}=i,p=u[0],v=Yo(s[0],"size"),b=Yo(s[1],"size");return{type:"rule",mode:d.mode,shift:p&&Yo(p,"size").value,width:v.value,height:b.value}},htmlBuilder(i,s){var u=zn.makeSpan(["mord","rule"],[],s),d=Uh(i.width,s),p=Uh(i.height,s),v=i.shift?Uh(i.shift,s):0;return u.style.borderRightWidth=Ri(d),u.style.borderTopWidth=Ri(p),u.style.bottom=Ri(v),u.width=d,u.height=p+v,u.depth=-v,u.maxFontSize=p*1.125*s.sizeMultiplier,u},mathmlBuilder(i,s){var u=Uh(i.width,s),d=Uh(i.height,s),p=i.shift?Uh(i.shift,s):0,v=s.color&&s.getColor()||"black",b=new vi.MathNode("mspace");b.setAttribute("mathbackground",v),b.setAttribute("width",Ri(u)),b.setAttribute("height",Ri(d));var y=new vi.MathNode("mpadded",[b]);return p>=0?y.setAttribute("height",Ri(p)):(y.setAttribute("height",Ri(p)),y.setAttribute("depth",Ri(-p))),y.setAttribute("voffset",Ri(p)),y}});function tqe(i,s,u){for(var d=d1(i,s,!1),p=s.sizeMultiplier/u.sizeMultiplier,v=0;v{var u=s.havingSize(i.size);return tqe(i.body,u,s)};Ji({type:"sizing",names:nqe,props:{numArgs:0,allowedInText:!0},handler:(i,s)=>{var{breakOnTokenText:u,funcName:d,parser:p}=i,v=p.parseExpression(!1,u);return{type:"sizing",mode:p.mode,size:nqe.indexOf(d)+1,body:v}},htmlBuilder:gVt,mathmlBuilder:(i,s)=>{var u=s.havingSize(i.size),d=j2(i.body,u),p=new vi.MathNode("mstyle",d);return p.setAttribute("mathsize",Ri(u.sizeMultiplier)),p}}),Ji({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(i,s,u)=>{var{parser:d}=i,p=!1,v=!1,b=u[0]&&Yo(u[0],"ordgroup");if(b)for(var y="",T=0;T{var u=zn.makeSpan([],[uu(i.body,s)]);if(!i.smashHeight&&!i.smashDepth)return u;if(i.smashHeight&&(u.height=0,u.children))for(var d=0;d{var u=new vi.MathNode("mpadded",[Ll(i.body,s)]);return i.smashHeight&&u.setAttribute("height","0px"),i.smashDepth&&u.setAttribute("depth","0px"),u}}),Ji({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(i,s,u){var{parser:d}=i,p=u[0],v=s[0];return{type:"sqrt",mode:d.mode,body:v,index:p}},htmlBuilder(i,s){var u=uu(i.body,s.havingCrampedStyle());u.height===0&&(u.height=s.fontMetrics().xHeight),u=zn.wrapFragment(u,s);var d=s.fontMetrics(),p=d.defaultRuleThickness,v=p;s.style.idu.height+u.depth+b&&(b=(b+P-u.height-u.depth)/2);var R=T.height-u.height-b-_;u.style.paddingLeft=Ri(A);var F=zn.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:u,wrapperClasses:["svg-align"]},{type:"kern",size:-(u.height+R)},{type:"elem",elem:T},{type:"kern",size:_}]},s);if(i.index){var j=s.havingStyle(Ta.SCRIPTSCRIPT),K=uu(i.index,j,s),ee=.6*(F.height-F.depth),ie=zn.makeVList({positionType:"shift",positionData:-ee,children:[{type:"elem",elem:K}]},s),oe=zn.makeSpan(["root"],[ie]);return zn.makeSpan(["mord","sqrt"],[oe,F],s)}else return zn.makeSpan(["mord","sqrt"],[F],s)},mathmlBuilder(i,s){var{body:u,index:d}=i;return d?new vi.MathNode("mroot",[Ll(u,s),Ll(d,s)]):new vi.MathNode("msqrt",[Ll(u,s)])}});var rqe={display:Ta.DISPLAY,text:Ta.TEXT,script:Ta.SCRIPT,scriptscript:Ta.SCRIPTSCRIPT};Ji({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i,s){var{breakOnTokenText:u,funcName:d,parser:p}=i,v=p.parseExpression(!0,u),b=d.slice(1,d.length-5);return{type:"styling",mode:p.mode,style:b,body:v}},htmlBuilder(i,s){var u=rqe[i.style],d=s.havingStyle(u).withFont("");return tqe(i.body,d,s)},mathmlBuilder(i,s){var u=rqe[i.style],d=s.havingStyle(u),p=j2(i.body,d),v=new vi.MathNode("mstyle",p),b={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},y=b[i.style];return v.setAttribute("scriptlevel",y[0]),v.setAttribute("displaystyle",y[1]),v}});var pVt=function(s,u){var d=s.base;if(d)if(d.type==="op"){var p=d.limits&&(u.style.size===Ta.DISPLAY.size||d.alwaysHandleSupSub);return p?PD:null}else if(d.type==="operatorname"){var v=d.alwaysHandleSupSub&&(u.style.size===Ta.DISPLAY.size||d.limits);return v?eqe:null}else{if(d.type==="accent")return Ya.isCharacterBox(d.base)?gbe:null;if(d.type==="horizBrace"){var b=!s.sub;return b===d.isOver?Xze:null}else return null}else return null};zC({type:"supsub",htmlBuilder(i,s){var u=pVt(i,s);if(u)return u(i,s);var{base:d,sup:p,sub:v}=i,b=uu(d,s),y,T,_=s.fontMetrics(),A=0,P=0,R=d&&Ya.isCharacterBox(d);if(p){var F=s.havingStyle(s.style.sup());y=uu(p,F,s),R||(A=b.height-F.fontMetrics().supDrop*F.sizeMultiplier/s.sizeMultiplier)}if(v){var j=s.havingStyle(s.style.sub());T=uu(v,j,s),R||(P=b.depth+j.fontMetrics().subDrop*j.sizeMultiplier/s.sizeMultiplier)}var K;s.style===Ta.DISPLAY?K=_.sup1:s.style.cramped?K=_.sup3:K=_.sup2;var ee=s.sizeMultiplier,ie=Ri(.5/_.ptPerEm/ee),oe=null;if(T){var pe=i.base&&i.base.type==="op"&&i.base.name&&(i.base.name==="\\oiint"||i.base.name==="\\oiiint");(b instanceof Bv||pe)&&(oe=Ri(-b.italic))}var be;if(y&&T){A=Math.max(A,K,y.depth+.25*_.xHeight),P=Math.max(P,_.sub2);var ae=_.defaultRuleThickness,ne=4*ae;if(A-y.depth-(T.height-P)0&&(A+=se,P-=se)}var de=[{type:"elem",elem:T,shift:P,marginRight:ie,marginLeft:oe},{type:"elem",elem:y,shift:-A,marginRight:ie}];be=zn.makeVList({positionType:"individualShift",children:de},s)}else if(T){P=Math.max(P,_.sub1,T.height-.8*_.xHeight);var X=[{type:"elem",elem:T,marginLeft:oe,marginRight:ie}];be=zn.makeVList({positionType:"shift",positionData:P,children:X},s)}else if(y)A=Math.max(A,K,y.depth+.25*_.xHeight),be=zn.makeVList({positionType:"shift",positionData:-A,children:[{type:"elem",elem:y,marginRight:ie}]},s);else throw new Error("supsub must have either sup or sub.");var ge=ube(b,"right")||"mord";return zn.makeSpan([ge],[b,zn.makeSpan(["msupsub"],[be])],s)},mathmlBuilder(i,s){var u=!1,d,p;i.base&&i.base.type==="horizBrace"&&(p=!!i.sup,p===i.base.isOver&&(u=!0,d=i.base.isOver)),i.base&&(i.base.type==="op"||i.base.type==="operatorname")&&(i.base.parentIsSupSub=!0);var v=[Ll(i.base,s)];i.sub&&v.push(Ll(i.sub,s)),i.sup&&v.push(Ll(i.sup,s));var b;if(u)b=d?"mover":"munder";else if(i.sub)if(i.sup){var _=i.base;_&&_.type==="op"&&_.limits&&s.style===Ta.DISPLAY||_&&_.type==="operatorname"&&_.alwaysHandleSupSub&&(s.style===Ta.DISPLAY||_.limits)?b="munderover":b="msubsup"}else{var T=i.base;T&&T.type==="op"&&T.limits&&(s.style===Ta.DISPLAY||T.alwaysHandleSupSub)||T&&T.type==="operatorname"&&T.alwaysHandleSupSub&&(T.limits||s.style===Ta.DISPLAY)?b="munder":b="msub"}else{var y=i.base;y&&y.type==="op"&&y.limits&&(s.style===Ta.DISPLAY||y.alwaysHandleSupSub)||y&&y.type==="operatorname"&&y.alwaysHandleSupSub&&(y.limits||s.style===Ta.DISPLAY)?b="mover":b="msup"}return new vi.MathNode(b,v)}}),zC({type:"atom",htmlBuilder(i,s){return zn.mathsym(i.text,i.mode,s,["m"+i.family])},mathmlBuilder(i,s){var u=new vi.MathNode("mo",[Rv(i.text,i.mode)]);if(i.family==="bin"){var d=fbe(i,s);d==="bold-italic"&&u.setAttribute("mathvariant",d)}else i.family==="punct"?u.setAttribute("separator","true"):(i.family==="open"||i.family==="close")&&u.setAttribute("stretchy","false");return u}});var iqe={mi:"italic",mn:"normal",mtext:"normal"};zC({type:"mathord",htmlBuilder(i,s){return zn.makeOrd(i,s,"mathord")},mathmlBuilder(i,s){var u=new vi.MathNode("mi",[Rv(i.text,i.mode,s)]),d=fbe(i,s)||"italic";return d!==iqe[u.type]&&u.setAttribute("mathvariant",d),u}}),zC({type:"textord",htmlBuilder(i,s){return zn.makeOrd(i,s,"textord")},mathmlBuilder(i,s){var u=Rv(i.text,i.mode,s),d=fbe(i,s)||"normal",p;return i.mode==="text"?p=new vi.MathNode("mtext",[u]):/[0-9]/.test(i.text)?p=new vi.MathNode("mn",[u]):i.text==="\\prime"?p=new vi.MathNode("mo",[u]):p=new vi.MathNode("mi",[u]),d!==iqe[p.type]&&p.setAttribute("mathvariant",d),p}});var Mbe={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Dbe={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};zC({type:"spacing",htmlBuilder(i,s){if(Dbe.hasOwnProperty(i.text)){var u=Dbe[i.text].className||"";if(i.mode==="text"){var d=zn.makeOrd(i,s,"textord");return d.classes.push(u),d}else return zn.makeSpan(["mspace",u],[zn.mathsym(i.text,i.mode,s)],s)}else{if(Mbe.hasOwnProperty(i.text))return zn.makeSpan(["mspace",Mbe[i.text]],[],s);throw new Ci('Unknown type of space "'+i.text+'"')}},mathmlBuilder(i,s){var u;if(Dbe.hasOwnProperty(i.text))u=new vi.MathNode("mtext",[new vi.TextNode(" ")]);else{if(Mbe.hasOwnProperty(i.text))return new vi.MathNode("mspace");throw new Ci('Unknown type of space "'+i.text+'"')}return u}});var sqe=()=>{var i=new vi.MathNode("mtd",[]);return i.setAttribute("width","50%"),i};zC({type:"tag",mathmlBuilder(i,s){var u=new vi.MathNode("mtable",[new vi.MathNode("mtr",[sqe(),new vi.MathNode("mtd",[_9(i.body,s)]),sqe(),new vi.MathNode("mtd",[_9(i.tag,s)])])]);return u.setAttribute("width","100%"),u}});var aqe={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},oqe={"\\textbf":"textbf","\\textmd":"textmd"},bVt={"\\textit":"textit","\\textup":"textup"},cqe=(i,s)=>{var u=i.font;return u?aqe[u]?s.withTextFontFamily(aqe[u]):oqe[u]?s.withTextFontWeight(oqe[u]):s.withTextFontShape(bVt[u]):s};Ji({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(i,s){var{parser:u,funcName:d}=i,p=s[0];return{type:"text",mode:u.mode,body:Xf(p),font:d}},htmlBuilder(i,s){var u=cqe(i,s),d=d1(i.body,u,!0);return zn.makeSpan(["mord","text"],d,u)},mathmlBuilder(i,s){var u=cqe(i,s);return _9(i.body,u)}}),Ji({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(i,s){var{parser:u}=i;return{type:"underline",mode:u.mode,body:s[0]}},htmlBuilder(i,s){var u=uu(i.body,s),d=zn.makeLineSpan("underline-line",s),p=s.fontMetrics().defaultRuleThickness,v=zn.makeVList({positionType:"top",positionData:u.height,children:[{type:"kern",size:p},{type:"elem",elem:d},{type:"kern",size:3*p},{type:"elem",elem:u}]},s);return zn.makeSpan(["mord","underline"],[v],s)},mathmlBuilder(i,s){var u=new vi.MathNode("mo",[new vi.TextNode("‾")]);u.setAttribute("stretchy","true");var d=new vi.MathNode("munder",[Ll(i.body,s),u]);return d.setAttribute("accentunder","true"),d}}),Ji({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(i,s){var{parser:u}=i;return{type:"vcenter",mode:u.mode,body:s[0]}},htmlBuilder(i,s){var u=uu(i.body,s),d=s.fontMetrics().axisHeight,p=.5*(u.height-d-(u.depth+d));return zn.makeVList({positionType:"shift",positionData:p,children:[{type:"elem",elem:u}]},s)},mathmlBuilder(i,s){return new vi.MathNode("mpadded",[Ll(i.body,s)],["vcenter"])}}),Ji({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(i,s,u){throw new Ci("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(i,s){for(var u=uqe(i),d=[],p=s.havingStyle(s.style.text()),v=0;vi.body.replace(/ /g,i.star?"␣":" "),L9=dze,lqe=`[ \r + ]`,mVt="\\\\[a-zA-Z@]+",vVt="\\\\[^\uD800-\uDFFF]",wVt="("+mVt+")"+lqe+"*",yVt=`\\\\( +|[ \r ]+ +?)[ \r ]*`,Ibe="[̀-ͯ]",xVt=new RegExp(Ibe+"+$"),kVt="("+lqe+"+)|"+(yVt+"|")+"([!-\\[\\]-‧‪-퟿豈-￿]"+(Ibe+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(Ibe+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+wVt)+("|"+vVt+")");class hqe{constructor(s,u){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=s,this.settings=u,this.tokenRegex=new RegExp(kVt,"g"),this.catcodes={"%":14,"~":13}}setCatcode(s,u){this.catcodes[s]=u}lex(){var s=this.input,u=this.tokenRegex.lastIndex;if(u===s.length)return new U4("EOF",new lm(this,u,u));var d=this.tokenRegex.exec(s);if(d===null||d.index!==u)throw new Ci("Unexpected character: '"+s[u]+"'",new U4(s[u],new lm(this,u,u+1)));var p=d[6]||d[3]||(d[2]?"\\ ":" ");if(this.catcodes[p]===14){var v=s.indexOf(` +`,this.tokenRegex.lastIndex);return v===-1?(this.tokenRegex.lastIndex=s.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=v+1,this.lex()}return new U4(p,new lm(this,u,this.tokenRegex.lastIndex))}}class EVt{constructor(s,u){s===void 0&&(s={}),u===void 0&&(u={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=u,this.builtins=s,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new Ci("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var s=this.undefStack.pop();for(var u in s)s.hasOwnProperty(u)&&(s[u]==null?delete this.current[u]:this.current[u]=s[u])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(s){return this.current.hasOwnProperty(s)||this.builtins.hasOwnProperty(s)}get(s){return this.current.hasOwnProperty(s)?this.current[s]:this.builtins[s]}set(s,u,d){if(d===void 0&&(d=!1),d){for(var p=0;p0&&(this.undefStack[this.undefStack.length-1][s]=u)}else{var v=this.undefStack[this.undefStack.length-1];v&&!v.hasOwnProperty(s)&&(v[s]=this.current[s])}u==null?delete this.current[s]:this.current[s]=u}}var TVt=$ze;et("\\noexpand",function(i){var s=i.popToken();return i.isExpandable(s.text)&&(s.noexpand=!0,s.treatAsRelax=!0),{tokens:[s],numArgs:0}}),et("\\expandafter",function(i){var s=i.popToken();return i.expandOnce(!0),{tokens:[s],numArgs:0}}),et("\\@firstoftwo",function(i){var s=i.consumeArgs(2);return{tokens:s[0],numArgs:0}}),et("\\@secondoftwo",function(i){var s=i.consumeArgs(2);return{tokens:s[1],numArgs:0}}),et("\\@ifnextchar",function(i){var s=i.consumeArgs(3);i.consumeSpaces();var u=i.future();return s[0].length===1&&s[0][0].text===u.text?{tokens:s[1],numArgs:0}:{tokens:s[2],numArgs:0}}),et("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),et("\\TextOrMath",function(i){var s=i.consumeArgs(2);return i.mode==="text"?{tokens:s[0],numArgs:0}:{tokens:s[1],numArgs:0}});var fqe={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};et("\\char",function(i){var s=i.popToken(),u,d="";if(s.text==="'")u=8,s=i.popToken();else if(s.text==='"')u=16,s=i.popToken();else if(s.text==="`")if(s=i.popToken(),s.text[0]==="\\")d=s.text.charCodeAt(1);else{if(s.text==="EOF")throw new Ci("\\char` missing argument");d=s.text.charCodeAt(0)}else u=10;if(u){if(d=fqe[s.text],d==null||d>=u)throw new Ci("Invalid base-"+u+" digit "+s.text);for(var p;(p=fqe[i.future().text])!=null&&p{var d=i.consumeArg().tokens;if(d.length!==1)throw new Ci("\\newcommand's first argument must be a macro name");var p=d[0].text,v=i.isDefined(p);if(v&&!s)throw new Ci("\\newcommand{"+p+"} attempting to redefine "+(p+"; use \\renewcommand"));if(!v&&!u)throw new Ci("\\renewcommand{"+p+"} when command "+p+" does not yet exist; use \\newcommand");var b=0;if(d=i.consumeArg().tokens,d.length===1&&d[0].text==="["){for(var y="",T=i.expandNextToken();T.text!=="]"&&T.text!=="EOF";)y+=T.text,T=i.expandNextToken();if(!y.match(/^\s*[0-9]+\s*$/))throw new Ci("Invalid number of arguments: "+y);b=parseInt(y),d=i.consumeArg().tokens}return i.macros.set(p,{tokens:d,numArgs:b}),""};et("\\newcommand",i=>Obe(i,!1,!0)),et("\\renewcommand",i=>Obe(i,!0,!1)),et("\\providecommand",i=>Obe(i,!0,!0)),et("\\message",i=>{var s=i.consumeArgs(1)[0];return console.log(s.reverse().map(u=>u.text).join("")),""}),et("\\errmessage",i=>{var s=i.consumeArgs(1)[0];return console.error(s.reverse().map(u=>u.text).join("")),""}),et("\\show",i=>{var s=i.popToken(),u=s.text;return console.log(s,i.macros.get(u),L9[u],Ul.math[u],Ul.text[u]),""}),et("\\bgroup","{"),et("\\egroup","}"),et("~","\\nobreakspace"),et("\\lq","`"),et("\\rq","'"),et("\\aa","\\r a"),et("\\AA","\\r A"),et("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`©}"),et("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),et("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`®}"),et("ℬ","\\mathscr{B}"),et("ℰ","\\mathscr{E}"),et("ℱ","\\mathscr{F}"),et("ℋ","\\mathscr{H}"),et("ℐ","\\mathscr{I}"),et("ℒ","\\mathscr{L}"),et("ℳ","\\mathscr{M}"),et("ℛ","\\mathscr{R}"),et("ℭ","\\mathfrak{C}"),et("ℌ","\\mathfrak{H}"),et("ℨ","\\mathfrak{Z}"),et("\\Bbbk","\\Bbb{k}"),et("·","\\cdotp"),et("\\llap","\\mathllap{\\textrm{#1}}"),et("\\rlap","\\mathrlap{\\textrm{#1}}"),et("\\clap","\\mathclap{\\textrm{#1}}"),et("\\mathstrut","\\vphantom{(}"),et("\\underbar","\\underline{\\text{#1}}"),et("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),et("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`≠}}"),et("\\ne","\\neq"),et("≠","\\neq"),et("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`∉}}"),et("∉","\\notin"),et("≘","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`≘}}"),et("≙","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`≘}}"),et("≚","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`≚}}"),et("≛","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`≛}}"),et("≝","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`≝}}"),et("≞","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`≞}}"),et("≟","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`≟}}"),et("⟂","\\perp"),et("‼","\\mathclose{!\\mkern-0.8mu!}"),et("∌","\\notni"),et("⌜","\\ulcorner"),et("⌝","\\urcorner"),et("⌞","\\llcorner"),et("⌟","\\lrcorner"),et("©","\\copyright"),et("®","\\textregistered"),et("️","\\textregistered"),et("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),et("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),et("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),et("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),et("\\vdots","\\mathord{\\varvdots\\rule{0pt}{15pt}}"),et("⋮","\\vdots"),et("\\varGamma","\\mathit{\\Gamma}"),et("\\varDelta","\\mathit{\\Delta}"),et("\\varTheta","\\mathit{\\Theta}"),et("\\varLambda","\\mathit{\\Lambda}"),et("\\varXi","\\mathit{\\Xi}"),et("\\varPi","\\mathit{\\Pi}"),et("\\varSigma","\\mathit{\\Sigma}"),et("\\varUpsilon","\\mathit{\\Upsilon}"),et("\\varPhi","\\mathit{\\Phi}"),et("\\varPsi","\\mathit{\\Psi}"),et("\\varOmega","\\mathit{\\Omega}"),et("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),et("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"),et("\\boxed","\\fbox{$\\displaystyle{#1}$}"),et("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),et("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),et("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");var dqe={",":"\\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"};et("\\dots",function(i){var s="\\dotso",u=i.expandAfterFuture().text;return u in dqe?s=dqe[u]:(u.slice(0,4)==="\\not"||u in Ul.math&&Ya.contains(["bin","rel"],Ul.math[u].group))&&(s="\\dotsb"),s});var Nbe={")":!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};et("\\dotso",function(i){var s=i.future().text;return s in Nbe?"\\ldots\\,":"\\ldots"}),et("\\dotsc",function(i){var s=i.future().text;return s in Nbe&&s!==","?"\\ldots\\,":"\\ldots"}),et("\\cdots",function(i){var s=i.future().text;return s in Nbe?"\\@cdots\\,":"\\@cdots"}),et("\\dotsb","\\cdots"),et("\\dotsm","\\cdots"),et("\\dotsi","\\!\\cdots"),et("\\dotsx","\\ldots\\,"),et("\\DOTSI","\\relax"),et("\\DOTSB","\\relax"),et("\\DOTSX","\\relax"),et("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),et("\\,","\\tmspace+{3mu}{.1667em}"),et("\\thinspace","\\,"),et("\\>","\\mskip{4mu}"),et("\\:","\\tmspace+{4mu}{.2222em}"),et("\\medspace","\\:"),et("\\;","\\tmspace+{5mu}{.2777em}"),et("\\thickspace","\\;"),et("\\!","\\tmspace-{3mu}{.1667em}"),et("\\negthinspace","\\!"),et("\\negmedspace","\\tmspace-{4mu}{.2222em}"),et("\\negthickspace","\\tmspace-{5mu}{.277em}"),et("\\enspace","\\kern.5em "),et("\\enskip","\\hskip.5em\\relax"),et("\\quad","\\hskip1em\\relax"),et("\\qquad","\\hskip2em\\relax"),et("\\tag","\\@ifstar\\tag@literal\\tag@paren"),et("\\tag@paren","\\tag@literal{({#1})}"),et("\\tag@literal",i=>{if(i.macros.get("\\df@tag"))throw new Ci("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"}),et("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),et("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),et("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),et("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),et("\\newline","\\\\\\relax"),et("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var gqe=Ri(K4["Main-Regular"]["T".charCodeAt(0)][1]-.7*K4["Main-Regular"]["A".charCodeAt(0)][1]);et("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+gqe+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}"),et("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+gqe+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}"),et("\\hspace","\\@ifstar\\@hspacer\\@hspace"),et("\\@hspace","\\hskip #1\\relax"),et("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),et("\\ordinarycolon",":"),et("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),et("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),et("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),et("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),et("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),et("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),et("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),et("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),et("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),et("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),et("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),et("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),et("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),et("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),et("∷","\\dblcolon"),et("∹","\\eqcolon"),et("≔","\\coloneqq"),et("≕","\\eqqcolon"),et("⩴","\\Coloneqq"),et("\\ratio","\\vcentcolon"),et("\\coloncolon","\\dblcolon"),et("\\colonequals","\\coloneqq"),et("\\coloncolonequals","\\Coloneqq"),et("\\equalscolon","\\eqqcolon"),et("\\equalscoloncolon","\\Eqqcolon"),et("\\colonminus","\\coloneq"),et("\\coloncolonminus","\\Coloneq"),et("\\minuscolon","\\eqcolon"),et("\\minuscoloncolon","\\Eqcolon"),et("\\coloncolonapprox","\\Colonapprox"),et("\\coloncolonsim","\\Colonsim"),et("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),et("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),et("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),et("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),et("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`∌}}"),et("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),et("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),et("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),et("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),et("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),et("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),et("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),et("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),et("\\gvertneqq","\\html@mathml{\\@gvertneqq}{≩}"),et("\\lvertneqq","\\html@mathml{\\@lvertneqq}{≨}"),et("\\ngeqq","\\html@mathml{\\@ngeqq}{≱}"),et("\\ngeqslant","\\html@mathml{\\@ngeqslant}{≱}"),et("\\nleqq","\\html@mathml{\\@nleqq}{≰}"),et("\\nleqslant","\\html@mathml{\\@nleqslant}{≰}"),et("\\nshortmid","\\html@mathml{\\@nshortmid}{∤}"),et("\\nshortparallel","\\html@mathml{\\@nshortparallel}{∦}"),et("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{⊈}"),et("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{⊉}"),et("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{⊊}"),et("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{⫋}"),et("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{⊋}"),et("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{⫌}"),et("\\imath","\\html@mathml{\\@imath}{ı}"),et("\\jmath","\\html@mathml{\\@jmath}{ȷ}"),et("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`⟦}}"),et("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`⟧}}"),et("⟦","\\llbracket"),et("⟧","\\rrbracket"),et("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`⦃}}"),et("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`⦄}}"),et("⦃","\\lBrace"),et("⦄","\\rBrace"),et("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`⦵}}"),et("⦵","\\minuso"),et("\\darr","\\downarrow"),et("\\dArr","\\Downarrow"),et("\\Darr","\\Downarrow"),et("\\lang","\\langle"),et("\\rang","\\rangle"),et("\\uarr","\\uparrow"),et("\\uArr","\\Uparrow"),et("\\Uarr","\\Uparrow"),et("\\N","\\mathbb{N}"),et("\\R","\\mathbb{R}"),et("\\Z","\\mathbb{Z}"),et("\\alef","\\aleph"),et("\\alefsym","\\aleph"),et("\\Alpha","\\mathrm{A}"),et("\\Beta","\\mathrm{B}"),et("\\bull","\\bullet"),et("\\Chi","\\mathrm{X}"),et("\\clubs","\\clubsuit"),et("\\cnums","\\mathbb{C}"),et("\\Complex","\\mathbb{C}"),et("\\Dagger","\\ddagger"),et("\\diamonds","\\diamondsuit"),et("\\empty","\\emptyset"),et("\\Epsilon","\\mathrm{E}"),et("\\Eta","\\mathrm{H}"),et("\\exist","\\exists"),et("\\harr","\\leftrightarrow"),et("\\hArr","\\Leftrightarrow"),et("\\Harr","\\Leftrightarrow"),et("\\hearts","\\heartsuit"),et("\\image","\\Im"),et("\\infin","\\infty"),et("\\Iota","\\mathrm{I}"),et("\\isin","\\in"),et("\\Kappa","\\mathrm{K}"),et("\\larr","\\leftarrow"),et("\\lArr","\\Leftarrow"),et("\\Larr","\\Leftarrow"),et("\\lrarr","\\leftrightarrow"),et("\\lrArr","\\Leftrightarrow"),et("\\Lrarr","\\Leftrightarrow"),et("\\Mu","\\mathrm{M}"),et("\\natnums","\\mathbb{N}"),et("\\Nu","\\mathrm{N}"),et("\\Omicron","\\mathrm{O}"),et("\\plusmn","\\pm"),et("\\rarr","\\rightarrow"),et("\\rArr","\\Rightarrow"),et("\\Rarr","\\Rightarrow"),et("\\real","\\Re"),et("\\reals","\\mathbb{R}"),et("\\Reals","\\mathbb{R}"),et("\\Rho","\\mathrm{P}"),et("\\sdot","\\cdot"),et("\\sect","\\S"),et("\\spades","\\spadesuit"),et("\\sub","\\subset"),et("\\sube","\\subseteq"),et("\\supe","\\supseteq"),et("\\Tau","\\mathrm{T}"),et("\\thetasym","\\vartheta"),et("\\weierp","\\wp"),et("\\Zeta","\\mathrm{Z}"),et("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),et("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),et("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),et("\\bra","\\mathinner{\\langle{#1}|}"),et("\\ket","\\mathinner{|{#1}\\rangle}"),et("\\braket","\\mathinner{\\langle{#1}\\rangle}"),et("\\Bra","\\left\\langle#1\\right|"),et("\\Ket","\\left|#1\\right\\rangle");var pqe=i=>s=>{var u=s.consumeArg().tokens,d=s.consumeArg().tokens,p=s.consumeArg().tokens,v=s.consumeArg().tokens,b=s.macros.get("|"),y=s.macros.get("\\|");s.macros.beginGroup();var T=P=>R=>{i&&(R.macros.set("|",b),p.length&&R.macros.set("\\|",y));var F=P;if(!P&&p.length){var j=R.future();j.text==="|"&&(R.popToken(),F=!0)}return{tokens:F?p:d,numArgs:0}};s.macros.set("|",T(!1)),p.length&&s.macros.set("\\|",T(!0));var _=s.consumeArg().tokens,A=s.expandTokens([...v,..._,...u]);return s.macros.endGroup(),{tokens:A.reverse(),numArgs:0}};et("\\bra@ket",pqe(!1)),et("\\bra@set",pqe(!0)),et("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),et("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),et("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),et("\\angln","{\\angl n}"),et("\\blue","\\textcolor{##6495ed}{#1}"),et("\\orange","\\textcolor{##ffa500}{#1}"),et("\\pink","\\textcolor{##ff00af}{#1}"),et("\\red","\\textcolor{##df0030}{#1}"),et("\\green","\\textcolor{##28ae7b}{#1}"),et("\\gray","\\textcolor{gray}{#1}"),et("\\purple","\\textcolor{##9d38bd}{#1}"),et("\\blueA","\\textcolor{##ccfaff}{#1}"),et("\\blueB","\\textcolor{##80f6ff}{#1}"),et("\\blueC","\\textcolor{##63d9ea}{#1}"),et("\\blueD","\\textcolor{##11accd}{#1}"),et("\\blueE","\\textcolor{##0c7f99}{#1}"),et("\\tealA","\\textcolor{##94fff5}{#1}"),et("\\tealB","\\textcolor{##26edd5}{#1}"),et("\\tealC","\\textcolor{##01d1c1}{#1}"),et("\\tealD","\\textcolor{##01a995}{#1}"),et("\\tealE","\\textcolor{##208170}{#1}"),et("\\greenA","\\textcolor{##b6ffb0}{#1}"),et("\\greenB","\\textcolor{##8af281}{#1}"),et("\\greenC","\\textcolor{##74cf70}{#1}"),et("\\greenD","\\textcolor{##1fab54}{#1}"),et("\\greenE","\\textcolor{##0d923f}{#1}"),et("\\goldA","\\textcolor{##ffd0a9}{#1}"),et("\\goldB","\\textcolor{##ffbb71}{#1}"),et("\\goldC","\\textcolor{##ff9c39}{#1}"),et("\\goldD","\\textcolor{##e07d10}{#1}"),et("\\goldE","\\textcolor{##a75a05}{#1}"),et("\\redA","\\textcolor{##fca9a9}{#1}"),et("\\redB","\\textcolor{##ff8482}{#1}"),et("\\redC","\\textcolor{##f9685d}{#1}"),et("\\redD","\\textcolor{##e84d39}{#1}"),et("\\redE","\\textcolor{##bc2612}{#1}"),et("\\maroonA","\\textcolor{##ffbde0}{#1}"),et("\\maroonB","\\textcolor{##ff92c6}{#1}"),et("\\maroonC","\\textcolor{##ed5fa6}{#1}"),et("\\maroonD","\\textcolor{##ca337c}{#1}"),et("\\maroonE","\\textcolor{##9e034e}{#1}"),et("\\purpleA","\\textcolor{##ddd7ff}{#1}"),et("\\purpleB","\\textcolor{##c6b9fc}{#1}"),et("\\purpleC","\\textcolor{##aa87ff}{#1}"),et("\\purpleD","\\textcolor{##7854ab}{#1}"),et("\\purpleE","\\textcolor{##543b78}{#1}"),et("\\mintA","\\textcolor{##f5f9e8}{#1}"),et("\\mintB","\\textcolor{##edf2df}{#1}"),et("\\mintC","\\textcolor{##e0e5cc}{#1}"),et("\\grayA","\\textcolor{##f6f7f7}{#1}"),et("\\grayB","\\textcolor{##f0f1f2}{#1}"),et("\\grayC","\\textcolor{##e3e5e6}{#1}"),et("\\grayD","\\textcolor{##d6d8da}{#1}"),et("\\grayE","\\textcolor{##babec2}{#1}"),et("\\grayF","\\textcolor{##888d93}{#1}"),et("\\grayG","\\textcolor{##626569}{#1}"),et("\\grayH","\\textcolor{##3b3e40}{#1}"),et("\\grayI","\\textcolor{##21242c}{#1}"),et("\\kaBlue","\\textcolor{##314453}{#1}"),et("\\kaGreen","\\textcolor{##71B307}{#1}");var bqe={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class CVt{constructor(s,u,d){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=u,this.expansionCount=0,this.feed(s),this.macros=new EVt(TVt,u.macros),this.mode=d,this.stack=[]}feed(s){this.lexer=new hqe(s,this.settings)}switchMode(s){this.mode=s}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(s){this.stack.push(s)}pushTokens(s){this.stack.push(...s)}scanArgument(s){var u,d,p;if(s){if(this.consumeSpaces(),this.future().text!=="[")return null;u=this.popToken(),{tokens:p,end:d}=this.consumeArg(["]"])}else({tokens:p,start:u,end:d}=this.consumeArg());return this.pushToken(new U4("EOF",d.loc)),this.pushTokens(p),u.range(d,"")}consumeSpaces(){for(;;){var s=this.future();if(s.text===" ")this.stack.pop();else break}}consumeArg(s){var u=[],d=s&&s.length>0;d||this.consumeSpaces();var p=this.future(),v,b=0,y=0;do{if(v=this.popToken(),u.push(v),v.text==="{")++b;else if(v.text==="}"){if(--b,b===-1)throw new Ci("Extra }",v)}else if(v.text==="EOF")throw new Ci("Unexpected end of input in a macro argument, expected '"+(s&&d?s[y]:"}")+"'",v);if(s&&d)if((b===0||b===1&&s[y]==="{")&&v.text===s[y]){if(++y,y===s.length){u.splice(-y,y);break}}else y=0}while(b!==0||d);return p.text==="{"&&u[u.length-1].text==="}"&&(u.pop(),u.shift()),u.reverse(),{tokens:u,start:p,end:v}}consumeArgs(s,u){if(u){if(u.length!==s+1)throw new Ci("The length of delimiters doesn't match the number of args!");for(var d=u[0],p=0;pthis.settings.maxExpand)throw new Ci("Too many expansions: infinite loop or need to increase maxExpand setting");var v=p.tokens,b=this.consumeArgs(p.numArgs,p.delimiters);if(p.numArgs){v=v.slice();for(var y=v.length-1;y>=0;--y){var T=v[y];if(T.text==="#"){if(y===0)throw new Ci("Incomplete placeholder at end of macro body",T);if(T=v[--y],T.text==="#")v.splice(y+1,1);else if(/^[1-9]$/.test(T.text))v.splice(y,2,...b[+T.text-1]);else throw new Ci("Not a valid argument number",T)}}}return this.pushTokens(v),v.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var s=this.stack.pop();return s.treatAsRelax&&(s.text="\\relax"),s}throw new Error}expandMacro(s){return this.macros.has(s)?this.expandTokens([new U4(s)]):void 0}expandTokens(s){var u=[],d=this.stack.length;for(this.pushTokens(s);this.stack.length>d;)if(this.expandOnce(!0)===!1){var p=this.stack.pop();p.treatAsRelax&&(p.noexpand=!1,p.treatAsRelax=!1),u.push(p)}return u}expandMacroAsText(s){var u=this.expandMacro(s);return u&&u.map(d=>d.text).join("")}_getExpansion(s){var u=this.macros.get(s);if(u==null)return u;if(s.length===1){var d=this.lexer.catcodes[s];if(d!=null&&d!==13)return}var p=typeof u=="function"?u(this):u;if(typeof p=="string"){var v=0;if(p.indexOf("#")!==-1)for(var b=p.replace(/##/g,"");b.indexOf("#"+(v+1))!==-1;)++v;for(var y=new hqe(p,this.settings),T=[],_=y.lex();_.text!=="EOF";)T.push(_),_=y.lex();T.reverse();var A={tokens:T,numArgs:v};return A}return p}isDefined(s){return this.macros.has(s)||L9.hasOwnProperty(s)||Ul.math.hasOwnProperty(s)||Ul.text.hasOwnProperty(s)||bqe.hasOwnProperty(s)}isExpandable(s){var u=this.macros.get(s);return u!=null?typeof u=="string"||typeof u=="function"||!u.unexpandable:L9.hasOwnProperty(s)&&!L9[s].primitive}}var mqe=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,TQ=Object.freeze({"₊":"+","₋":"-","₌":"=","₍":"(","₎":")","₀":"0","₁":"1","₂":"2","₃":"3","₄":"4","₅":"5","₆":"6","₇":"7","₈":"8","₉":"9","ₐ":"a","ₑ":"e","ₕ":"h","ᵢ":"i","ⱼ":"j","ₖ":"k","ₗ":"l","ₘ":"m","ₙ":"n","ₒ":"o","ₚ":"p","ᵣ":"r","ₛ":"s","ₜ":"t","ᵤ":"u","ᵥ":"v","ₓ":"x","ᵦ":"β","ᵧ":"γ","ᵨ":"ρ","ᵩ":"ϕ","ᵪ":"χ","⁺":"+","⁻":"-","⁼":"=","⁽":"(","⁾":")","⁰":"0","¹":"1","²":"2","³":"3","⁴":"4","⁵":"5","⁶":"6","⁷":"7","⁸":"8","⁹":"9","ᴬ":"A","ᴮ":"B","ᴰ":"D","ᴱ":"E","ᴳ":"G","ᴴ":"H","ᴵ":"I","ᴶ":"J","ᴷ":"K","ᴸ":"L","ᴹ":"M","ᴺ":"N","ᴼ":"O","ᴾ":"P","ᴿ":"R","ᵀ":"T","ᵁ":"U","ⱽ":"V","ᵂ":"W","ᵃ":"a","ᵇ":"b","ᶜ":"c","ᵈ":"d","ᵉ":"e","ᶠ":"f","ᵍ":"g",ʰ:"h","ⁱ":"i",ʲ:"j","ᵏ":"k",ˡ:"l","ᵐ":"m",ⁿ:"n","ᵒ":"o","ᵖ":"p",ʳ:"r",ˢ:"s","ᵗ":"t","ᵘ":"u","ᵛ":"v",ʷ:"w",ˣ:"x",ʸ:"y","ᶻ":"z","ᵝ":"β","ᵞ":"γ","ᵟ":"δ","ᵠ":"ϕ","ᵡ":"χ","ᶿ":"θ"}),Pbe={"́":{text:"\\'",math:"\\acute"},"̀":{text:"\\`",math:"\\grave"},"̈":{text:'\\"',math:"\\ddot"},"̃":{text:"\\~",math:"\\tilde"},"̄":{text:"\\=",math:"\\bar"},"̆":{text:"\\u",math:"\\breve"},"̌":{text:"\\v",math:"\\check"},"̂":{text:"\\^",math:"\\hat"},"̇":{text:"\\.",math:"\\dot"},"̊":{text:"\\r",math:"\\mathring"},"̋":{text:"\\H"},"̧":{text:"\\c"}},vqe={á:"á",à:"à",ä:"ä",ǟ:"ǟ",ã:"ã",ā:"ā",ă:"ă",ắ:"ắ",ằ:"ằ",ẵ:"ẵ",ǎ:"ǎ",â:"â",ấ:"ấ",ầ:"ầ",ẫ:"ẫ",ȧ:"ȧ",ǡ:"ǡ",å:"å",ǻ:"ǻ",ḃ:"ḃ",ć:"ć",ḉ:"ḉ",č:"č",ĉ:"ĉ",ċ:"ċ",ç:"ç",ď:"ď",ḋ:"ḋ",ḑ:"ḑ",é:"é",è:"è",ë:"ë",ẽ:"ẽ",ē:"ē",ḗ:"ḗ",ḕ:"ḕ",ĕ:"ĕ",ḝ:"ḝ",ě:"ě",ê:"ê",ế:"ế",ề:"ề",ễ:"ễ",ė:"ė",ȩ:"ȩ",ḟ:"ḟ",ǵ:"ǵ",ḡ:"ḡ",ğ:"ğ",ǧ:"ǧ",ĝ:"ĝ",ġ:"ġ",ģ:"ģ",ḧ:"ḧ",ȟ:"ȟ",ĥ:"ĥ",ḣ:"ḣ",ḩ:"ḩ",í:"í",ì:"ì",ï:"ï",ḯ:"ḯ",ĩ:"ĩ",ī:"ī",ĭ:"ĭ",ǐ:"ǐ",î:"î",ǰ:"ǰ",ĵ:"ĵ",ḱ:"ḱ",ǩ:"ǩ",ķ:"ķ",ĺ:"ĺ",ľ:"ľ",ļ:"ļ",ḿ:"ḿ",ṁ:"ṁ",ń:"ń",ǹ:"ǹ",ñ:"ñ",ň:"ň",ṅ:"ṅ",ņ:"ņ",ó:"ó",ò:"ò",ö:"ö",ȫ:"ȫ",õ:"õ",ṍ:"ṍ",ṏ:"ṏ",ȭ:"ȭ",ō:"ō",ṓ:"ṓ",ṑ:"ṑ",ŏ:"ŏ",ǒ:"ǒ",ô:"ô",ố:"ố",ồ:"ồ",ỗ:"ỗ",ȯ:"ȯ",ȱ:"ȱ",ő:"ő",ṕ:"ṕ",ṗ:"ṗ",ŕ:"ŕ",ř:"ř",ṙ:"ṙ",ŗ:"ŗ",ś:"ś",ṥ:"ṥ",š:"š",ṧ:"ṧ",ŝ:"ŝ",ṡ:"ṡ",ş:"ş",ẗ:"ẗ",ť:"ť",ṫ:"ṫ",ţ:"ţ",ú:"ú",ù:"ù",ü:"ü",ǘ:"ǘ",ǜ:"ǜ",ǖ:"ǖ",ǚ:"ǚ",ũ:"ũ",ṹ:"ṹ",ū:"ū",ṻ:"ṻ",ŭ:"ŭ",ǔ:"ǔ",û:"û",ů:"ů",ű:"ű",ṽ:"ṽ",ẃ:"ẃ",ẁ:"ẁ",ẅ:"ẅ",ŵ:"ŵ",ẇ:"ẇ",ẘ:"ẘ",ẍ:"ẍ",ẋ:"ẋ",ý:"ý",ỳ:"ỳ",ÿ:"ÿ",ỹ:"ỹ",ȳ:"ȳ",ŷ:"ŷ",ẏ:"ẏ",ẙ:"ẙ",ź:"ź",ž:"ž",ẑ:"ẑ",ż:"ż",Á:"Á",À:"À",Ä:"Ä",Ǟ:"Ǟ",Ã:"Ã",Ā:"Ā",Ă:"Ă",Ắ:"Ắ",Ằ:"Ằ",Ẵ:"Ẵ",Ǎ:"Ǎ",Â:"Â",Ấ:"Ấ",Ầ:"Ầ",Ẫ:"Ẫ",Ȧ:"Ȧ",Ǡ:"Ǡ",Å:"Å",Ǻ:"Ǻ",Ḃ:"Ḃ",Ć:"Ć",Ḉ:"Ḉ",Č:"Č",Ĉ:"Ĉ",Ċ:"Ċ",Ç:"Ç",Ď:"Ď",Ḋ:"Ḋ",Ḑ:"Ḑ",É:"É",È:"È",Ë:"Ë",Ẽ:"Ẽ",Ē:"Ē",Ḗ:"Ḗ",Ḕ:"Ḕ",Ĕ:"Ĕ",Ḝ:"Ḝ",Ě:"Ě",Ê:"Ê",Ế:"Ế",Ề:"Ề",Ễ:"Ễ",Ė:"Ė",Ȩ:"Ȩ",Ḟ:"Ḟ",Ǵ:"Ǵ",Ḡ:"Ḡ",Ğ:"Ğ",Ǧ:"Ǧ",Ĝ:"Ĝ",Ġ:"Ġ",Ģ:"Ģ",Ḧ:"Ḧ",Ȟ:"Ȟ",Ĥ:"Ĥ",Ḣ:"Ḣ",Ḩ:"Ḩ",Í:"Í",Ì:"Ì",Ï:"Ï",Ḯ:"Ḯ",Ĩ:"Ĩ",Ī:"Ī",Ĭ:"Ĭ",Ǐ:"Ǐ",Î:"Î",İ:"İ",Ĵ:"Ĵ",Ḱ:"Ḱ",Ǩ:"Ǩ",Ķ:"Ķ",Ĺ:"Ĺ",Ľ:"Ľ",Ļ:"Ļ",Ḿ:"Ḿ",Ṁ:"Ṁ",Ń:"Ń",Ǹ:"Ǹ",Ñ:"Ñ",Ň:"Ň",Ṅ:"Ṅ",Ņ:"Ņ",Ó:"Ó",Ò:"Ò",Ö:"Ö",Ȫ:"Ȫ",Õ:"Õ",Ṍ:"Ṍ",Ṏ:"Ṏ",Ȭ:"Ȭ",Ō:"Ō",Ṓ:"Ṓ",Ṑ:"Ṑ",Ŏ:"Ŏ",Ǒ:"Ǒ",Ô:"Ô",Ố:"Ố",Ồ:"Ồ",Ỗ:"Ỗ",Ȯ:"Ȯ",Ȱ:"Ȱ",Ő:"Ő",Ṕ:"Ṕ",Ṗ:"Ṗ",Ŕ:"Ŕ",Ř:"Ř",Ṙ:"Ṙ",Ŗ:"Ŗ",Ś:"Ś",Ṥ:"Ṥ",Š:"Š",Ṧ:"Ṧ",Ŝ:"Ŝ",Ṡ:"Ṡ",Ş:"Ş",Ť:"Ť",Ṫ:"Ṫ",Ţ:"Ţ",Ú:"Ú",Ù:"Ù",Ü:"Ü",Ǘ:"Ǘ",Ǜ:"Ǜ",Ǖ:"Ǖ",Ǚ:"Ǚ",Ũ:"Ũ",Ṹ:"Ṹ",Ū:"Ū",Ṻ:"Ṻ",Ŭ:"Ŭ",Ǔ:"Ǔ",Û:"Û",Ů:"Ů",Ű:"Ű",Ṽ:"Ṽ",Ẃ:"Ẃ",Ẁ:"Ẁ",Ẅ:"Ẅ",Ŵ:"Ŵ",Ẇ:"Ẇ",Ẍ:"Ẍ",Ẋ:"Ẋ",Ý:"Ý",Ỳ:"Ỳ",Ÿ:"Ÿ",Ỹ:"Ỹ",Ȳ:"Ȳ",Ŷ:"Ŷ",Ẏ:"Ẏ",Ź:"Ź",Ž:"Ž",Ẑ:"Ẑ",Ż:"Ż",ά:"ά",ὰ:"ὰ",ᾱ:"ᾱ",ᾰ:"ᾰ",έ:"έ",ὲ:"ὲ",ή:"ή",ὴ:"ὴ",ί:"ί",ὶ:"ὶ",ϊ:"ϊ",ΐ:"ΐ",ῒ:"ῒ",ῑ:"ῑ",ῐ:"ῐ",ό:"ό",ὸ:"ὸ",ύ:"ύ",ὺ:"ὺ",ϋ:"ϋ",ΰ:"ΰ",ῢ:"ῢ",ῡ:"ῡ",ῠ:"ῠ",ώ:"ώ",ὼ:"ὼ",Ύ:"Ύ",Ὺ:"Ὺ",Ϋ:"Ϋ",Ῡ:"Ῡ",Ῠ:"Ῠ",Ώ:"Ώ",Ὼ:"Ὼ"};class gR{constructor(s,u){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 CVt(s,u,this.mode),this.settings=u,this.leftrightDepth=0}expect(s,u){if(u===void 0&&(u=!0),this.fetch().text!==s)throw new Ci("Expected '"+s+"', got '"+this.fetch().text+"'",this.fetch());u&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(s){this.mode=s,this.gullet.switchMode(s)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var s=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),s}finally{this.gullet.endGroups()}}subparse(s){var u=this.nextToken;this.consume(),this.gullet.pushToken(new U4("}")),this.gullet.pushTokens(s);var d=this.parseExpression(!1);return this.expect("}"),this.nextToken=u,d}parseExpression(s,u){for(var d=[];;){this.mode==="math"&&this.consumeSpaces();var p=this.fetch();if(gR.endOfExpression.indexOf(p.text)!==-1||u&&p.text===u||s&&L9[p.text]&&L9[p.text].infix)break;var v=this.parseAtom(u);if(v){if(v.type==="internal")continue}else break;d.push(v)}return this.mode==="text"&&this.formLigatures(d),this.handleInfixNodes(d)}handleInfixNodes(s){for(var u=-1,d,p=0;p=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+u[0]+'" used in math mode',s);var y=Ul[this.mode][u].group,T=lm.range(s),_;if(dHt.hasOwnProperty(y)){var A=y;_={type:"atom",mode:this.mode,family:A,loc:T,text:u}}else _={type:y,mode:this.mode,loc:T,text:u};b=_}else if(u.charCodeAt(0)>=128)this.settings.strict&&(K$e(u.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+u[0]+'" used in math mode',s):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+u[0]+'"'+(" ("+u.charCodeAt(0)+")"),s)),b={type:"textord",mode:"text",loc:lm.range(s),text:u};else return null;if(this.consume(),v)for(var P=0;P"u"&&(_s.yylloc={});var j0=_s.yylloc;on.push(j0);var pm=_s.options&&_s.options.ranges;typeof tl.yy.parseError=="function"?this.parseError=tl.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ml(){var kh;return kh=At.pop()||_s.lex()||Pa,typeof kh!="number"&&(kh instanceof Array&&(At=kh,kh=At.pop()),kh=qn.symbols_[kh]||kh),kh}for(var Xc,Bc,ja,Ou,Sa={},Po,Fc,xa,Ba;;){if(Bc=Un[Un.length-1],this.defaultActions[Bc]?ja=this.defaultActions[Bc]:((Xc===null||typeof Xc>"u")&&(Xc=Ml()),ja=fn[Bc]&&fn[Bc][Xc]),typeof ja>"u"||!ja.length||!ja[0]){var ga="";Ba=[];for(Po in fn[Bc])this.terminals_[Po]&&Po>$o&&Ba.push("'"+this.terminals_[Po]+"'");_s.showPosition?ga="Parse error on line "+(oo+1)+`: +`+_s.showPosition()+` +Expecting `+Ba.join(", ")+", got '"+(this.terminals_[Xc]||Xc)+"'":ga="Parse error on line "+(oo+1)+": Unexpected "+(Xc==Pa?"end of input":"'"+(this.terminals_[Xc]||Xc)+"'"),this.parseError(ga,{text:_s.match,token:this.terminals_[Xc]||Xc,line:_s.yylineno,loc:j0,expected:Ba})}if(ja[0]instanceof Array&&ja.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Bc+", token: "+Xc);switch(ja[0]){case 1:Un.push(Xc),wt.push(_s.yytext),on.push(_s.yylloc),Un.push(ja[1]),Xc=null,jo=_s.yyleng,An=_s.yytext,oo=_s.yylineno,j0=_s.yylloc;break;case 2:if(Fc=this.productions_[ja[1]][1],Sa.$=wt[wt.length-Fc],Sa._$={first_line:on[on.length-(Fc||1)].first_line,last_line:on[on.length-1].last_line,first_column:on[on.length-(Fc||1)].first_column,last_column:on[on.length-1].last_column},pm&&(Sa._$.range=[on[on.length-(Fc||1)].range[0],on[on.length-1].range[1]]),Ou=this.performAction.apply(Sa,[An,jo,oo,tl.yy,ja[1],wt,on].concat(wo)),typeof Ou<"u")return Ou;Fc&&(Un=Un.slice(0,-1*Fc*2),wt=wt.slice(0,-1*Fc),on=on.slice(0,-1*Fc)),Un.push(this.productions_[ja[1]][0]),wt.push(Sa.$),on.push(Sa._$),xa=fn[Un[Un.length-2]][Un[Un.length-1]],Un.push(xa);break;case 3:return!0}}return!0}},zs=function(){var Tr={EOF:1,parseError:function(qn,Un){if(this.yy.parser)this.yy.parser.parseError(qn,Un);else throw new Error(qn)},setInput:function(Fn,qn){return this.yy=qn||this.yy||{},this._input=Fn,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},input:function(){var Fn=this._input[0];this.yytext+=Fn,this.yyleng++,this.offset++,this.match+=Fn,this.matched+=Fn;var qn=Fn.match(/(?:\r\n?|\n).*/g);return qn?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Fn},unput:function(Fn){var qn=Fn.length,Un=Fn.split(/(?:\r\n?|\n)/g);this._input=Fn+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-qn),this.offset-=qn;var At=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),Un.length-1&&(this.yylineno-=Un.length-1);var wt=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:Un?(Un.length===At.length?this.yylloc.first_column:0)+At[At.length-Un.length].length-Un[0].length:this.yylloc.first_column-qn},this.options.ranges&&(this.yylloc.range=[wt[0],wt[0]+this.yyleng-qn]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(Fn){this.unput(this.match.slice(Fn))},pastInput:function(){var Fn=this.matched.substr(0,this.matched.length-this.match.length);return(Fn.length>20?"...":"")+Fn.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var Fn=this.match;return Fn.length<20&&(Fn+=this._input.substr(0,20-Fn.length)),(Fn.substr(0,20)+(Fn.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var Fn=this.pastInput(),qn=new Array(Fn.length+1).join("-");return Fn+this.upcomingInput()+` +`+qn+"^"},test_match:function(Fn,qn){var Un,At,wt;if(this.options.backtrack_lexer&&(wt={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&&(wt.yylloc.range=this.yylloc.range.slice(0))),At=Fn[0].match(/(?:\r\n?|\n).*/g),At&&(this.yylineno+=At.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:At?At[At.length-1].length-At[At.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+Fn[0].length},this.yytext+=Fn[0],this.match+=Fn[0],this.matches=Fn,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(Fn[0].length),this.matched+=Fn[0],Un=this.performAction.call(this,this.yy,this,qn,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Un)return Un;if(this._backtrack){for(var on in wt)this[on]=wt[on];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Fn,qn,Un,At;this._more||(this.yytext="",this.match="");for(var wt=this._currentRules(),on=0;onqn[0].length)){if(qn=Un,At=on,this.options.backtrack_lexer){if(Fn=this.test_match(Un,wt[on]),Fn!==!1)return Fn;if(this._backtrack){qn=!1;continue}else return!1}else if(!this.options.flex)break}return qn?(Fn=this.test_match(qn,wt[At]),Fn!==!1?Fn:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var qn=this.next();return qn||this.lex()},begin:function(qn){this.conditionStack.push(qn)},popState:function(){var qn=this.conditionStack.length-1;return qn>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(qn){return qn=this.conditionStack.length-1-Math.abs(qn||0),qn>=0?this.conditionStack[qn]:"INITIAL"},pushState:function(qn){this.begin(qn)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(qn,Un,At,wt){switch(At){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;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),26;case 9:return this.popState(),"acc_descr_value";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;case 23:return this.begin("person"),44;case 24:return this.begin("system_ext_queue"),51;case 25:return this.begin("system_ext_db"),50;case 26:return this.begin("system_ext"),49;case 27:return this.begin("system_queue"),48;case 28:return this.begin("system_db"),47;case 29:return this.begin("system"),46;case 30:return this.begin("boundary"),37;case 31:return this.begin("enterprise_boundary"),34;case 32:return this.begin("system_boundary"),36;case 33:return this.begin("container_ext_queue"),57;case 34:return this.begin("container_ext_db"),56;case 35:return this.begin("container_ext"),55;case 36:return this.begin("container_queue"),54;case 37:return this.begin("container_db"),53;case 38:return this.begin("container"),52;case 39:return this.begin("container_boundary"),38;case 40:return this.begin("component_ext_queue"),63;case 41:return this.begin("component_ext_db"),62;case 42:return this.begin("component_ext"),61;case 43:return this.begin("component_queue"),60;case 44:return this.begin("component_db"),59;case 45:return this.begin("component"),58;case 46:return this.begin("node"),39;case 47:return this.begin("node"),39;case 48:return this.begin("node_l"),40;case 49:return this.begin("node_r"),41;case 50:return this.begin("rel"),64;case 51:return this.begin("birel"),65;case 52:return this.begin("rel_u"),66;case 53:return this.begin("rel_u"),66;case 54:return this.begin("rel_d"),67;case 55:return this.begin("rel_d"),67;case 56:return this.begin("rel_l"),68;case 57:return this.begin("rel_l"),68;case 58:return this.begin("rel_r"),69;case 59:return this.begin("rel_r"),69;case 60:return this.begin("rel_b"),70;case 61:return this.begin("rel_index"),71;case 62:return this.begin("update_el_style"),72;case 63:return this.begin("update_rel_style"),73;case 64:return this.begin("update_layout_config"),74;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";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";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}},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 Tr}();Ma.lexer=zs;function ao(){this.yy={}}return ao.prototype=Ma,Ma.Parser=ao,new ao}();CQ.parser=CQ;const DVt=CQ;let R3=[],M9=[""],Op="global",j3="",Q4=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],pR=[],Rbe="",jbe=!1,SQ=4,_Q=2;var xqe;const IVt=function(){return xqe},OVt=function(i){xqe=Yf(i,qt())},NVt=function(i,s,u,d,p,v,b,y,T){if(i==null||s===void 0||s===null||u===void 0||u===null||d===void 0||d===null)return;let _={};const A=pR.find(P=>P.from===s&&P.to===u);if(A?_=A:pR.push(_),_.type=i,_.from=s,_.to=u,_.label={text:d},p==null)_.techn={text:""};else if(typeof p=="object"){let[P,R]=Object.entries(p)[0];_[P]={text:R}}else _.techn={text:p};if(v==null)_.descr={text:""};else if(typeof v=="object"){let[P,R]=Object.entries(v)[0];_[P]={text:R}}else _.descr={text:v};if(typeof b=="object"){let[P,R]=Object.entries(b)[0];_[P]=R}else _.sprite=b;if(typeof y=="object"){let[P,R]=Object.entries(y)[0];_[P]=R}else _.tags=y;if(typeof T=="object"){let[P,R]=Object.entries(T)[0];_[P]=R}else _.link=T;_.wrap=D9()},PVt=function(i,s,u,d,p,v,b){if(s===null||u===null)return;let y={};const T=R3.find(_=>_.alias===s);if(T&&s===T.alias?y=T:(y.alias=s,R3.push(y)),u==null?y.label={text:""}:y.label={text:u},d==null)y.descr={text:""};else if(typeof d=="object"){let[_,A]=Object.entries(d)[0];y[_]={text:A}}else y.descr={text:d};if(typeof p=="object"){let[_,A]=Object.entries(p)[0];y[_]=A}else y.sprite=p;if(typeof v=="object"){let[_,A]=Object.entries(v)[0];y[_]=A}else y.tags=v;if(typeof b=="object"){let[_,A]=Object.entries(b)[0];y[_]=A}else y.link=b;y.typeC4Shape={text:i},y.parentBoundary=Op,y.wrap=D9()},BVt=function(i,s,u,d,p,v,b,y){if(s===null||u===null)return;let T={};const _=R3.find(A=>A.alias===s);if(_&&s===_.alias?T=_:(T.alias=s,R3.push(T)),u==null?T.label={text:""}:T.label={text:u},d==null)T.techn={text:""};else if(typeof d=="object"){let[A,P]=Object.entries(d)[0];T[A]={text:P}}else T.techn={text:d};if(p==null)T.descr={text:""};else if(typeof p=="object"){let[A,P]=Object.entries(p)[0];T[A]={text:P}}else T.descr={text:p};if(typeof v=="object"){let[A,P]=Object.entries(v)[0];T[A]=P}else T.sprite=v;if(typeof b=="object"){let[A,P]=Object.entries(b)[0];T[A]=P}else T.tags=b;if(typeof y=="object"){let[A,P]=Object.entries(y)[0];T[A]=P}else T.link=y;T.wrap=D9(),T.typeC4Shape={text:i},T.parentBoundary=Op},FVt=function(i,s,u,d,p,v,b,y){if(s===null||u===null)return;let T={};const _=R3.find(A=>A.alias===s);if(_&&s===_.alias?T=_:(T.alias=s,R3.push(T)),u==null?T.label={text:""}:T.label={text:u},d==null)T.techn={text:""};else if(typeof d=="object"){let[A,P]=Object.entries(d)[0];T[A]={text:P}}else T.techn={text:d};if(p==null)T.descr={text:""};else if(typeof p=="object"){let[A,P]=Object.entries(p)[0];T[A]={text:P}}else T.descr={text:p};if(typeof v=="object"){let[A,P]=Object.entries(v)[0];T[A]=P}else T.sprite=v;if(typeof b=="object"){let[A,P]=Object.entries(b)[0];T[A]=P}else T.tags=b;if(typeof y=="object"){let[A,P]=Object.entries(y)[0];T[A]=P}else T.link=y;T.wrap=D9(),T.typeC4Shape={text:i},T.parentBoundary=Op},RVt=function(i,s,u,d,p){if(i===null||s===null)return;let v={};const b=Q4.find(y=>y.alias===i);if(b&&i===b.alias?v=b:(v.alias=i,Q4.push(v)),s==null?v.label={text:""}:v.label={text:s},u==null)v.type={text:"system"};else if(typeof u=="object"){let[y,T]=Object.entries(u)[0];v[y]={text:T}}else v.type={text:u};if(typeof d=="object"){let[y,T]=Object.entries(d)[0];v[y]=T}else v.tags=d;if(typeof p=="object"){let[y,T]=Object.entries(p)[0];v[y]=T}else v.link=p;v.parentBoundary=Op,v.wrap=D9(),j3=Op,Op=i,M9.push(j3)},jVt=function(i,s,u,d,p){if(i===null||s===null)return;let v={};const b=Q4.find(y=>y.alias===i);if(b&&i===b.alias?v=b:(v.alias=i,Q4.push(v)),s==null?v.label={text:""}:v.label={text:s},u==null)v.type={text:"container"};else if(typeof u=="object"){let[y,T]=Object.entries(u)[0];v[y]={text:T}}else v.type={text:u};if(typeof d=="object"){let[y,T]=Object.entries(d)[0];v[y]=T}else v.tags=d;if(typeof p=="object"){let[y,T]=Object.entries(p)[0];v[y]=T}else v.link=p;v.parentBoundary=Op,v.wrap=D9(),j3=Op,Op=i,M9.push(j3)},$Vt=function(i,s,u,d,p,v,b,y){if(s===null||u===null)return;let T={};const _=Q4.find(A=>A.alias===s);if(_&&s===_.alias?T=_:(T.alias=s,Q4.push(T)),u==null?T.label={text:""}:T.label={text:u},d==null)T.type={text:"node"};else if(typeof d=="object"){let[A,P]=Object.entries(d)[0];T[A]={text:P}}else T.type={text:d};if(p==null)T.descr={text:""};else if(typeof p=="object"){let[A,P]=Object.entries(p)[0];T[A]={text:P}}else T.descr={text:p};if(typeof b=="object"){let[A,P]=Object.entries(b)[0];T[A]=P}else T.tags=b;if(typeof y=="object"){let[A,P]=Object.entries(y)[0];T[A]=P}else T.link=y;T.nodeType=i,T.parentBoundary=Op,T.wrap=D9(),j3=Op,Op=s,M9.push(j3)},zVt=function(){Op=j3,M9.pop(),j3=M9.pop(),M9.push(j3)},qVt=function(i,s,u,d,p,v,b,y,T,_,A){let P=R3.find(R=>R.alias===s);if(!(P===void 0&&(P=Q4.find(R=>R.alias===s),P===void 0))){if(u!=null)if(typeof u=="object"){let[R,F]=Object.entries(u)[0];P[R]=F}else P.bgColor=u;if(d!=null)if(typeof d=="object"){let[R,F]=Object.entries(d)[0];P[R]=F}else P.fontColor=d;if(p!=null)if(typeof p=="object"){let[R,F]=Object.entries(p)[0];P[R]=F}else P.borderColor=p;if(v!=null)if(typeof v=="object"){let[R,F]=Object.entries(v)[0];P[R]=F}else P.shadowing=v;if(b!=null)if(typeof b=="object"){let[R,F]=Object.entries(b)[0];P[R]=F}else P.shape=b;if(y!=null)if(typeof y=="object"){let[R,F]=Object.entries(y)[0];P[R]=F}else P.sprite=y;if(T!=null)if(typeof T=="object"){let[R,F]=Object.entries(T)[0];P[R]=F}else P.techn=T;if(_!=null)if(typeof _=="object"){let[R,F]=Object.entries(_)[0];P[R]=F}else P.legendText=_;if(A!=null)if(typeof A=="object"){let[R,F]=Object.entries(A)[0];P[R]=F}else P.legendSprite=A}},HVt=function(i,s,u,d,p,v,b){const y=pR.find(T=>T.from===s&&T.to===u);if(y!==void 0){if(d!=null)if(typeof d=="object"){let[T,_]=Object.entries(d)[0];y[T]=_}else y.textColor=d;if(p!=null)if(typeof p=="object"){let[T,_]=Object.entries(p)[0];y[T]=_}else y.lineColor=p;if(v!=null)if(typeof v=="object"){let[T,_]=Object.entries(v)[0];y[T]=parseInt(_)}else y.offsetX=parseInt(v);if(b!=null)if(typeof b=="object"){let[T,_]=Object.entries(b)[0];y[T]=parseInt(_)}else y.offsetY=parseInt(b)}},VVt=function(i,s,u){let d=SQ,p=_Q;if(typeof s=="object"){const v=Object.values(s)[0];d=parseInt(v)}else d=parseInt(s);if(typeof u=="object"){const v=Object.values(u)[0];p=parseInt(v)}else p=parseInt(u);d>=1&&(SQ=d),p>=1&&(_Q=p)},UVt=function(){return SQ},GVt=function(){return _Q},KVt=function(){return Op},WVt=function(){return j3},kqe=function(i){return i==null?R3:R3.filter(s=>s.parentBoundary===i)},YVt=function(i){return R3.find(s=>s.alias===i)},XVt=function(i){return Object.keys(kqe(i))},Eqe=function(i){return i==null?Q4:Q4.filter(s=>s.parentBoundary===i)},QVt=Eqe,JVt=function(){return pR},ZVt=function(){return Rbe},eUt=function(i){jbe=i},D9=function(){return jbe},$be={addPersonOrSystem:PVt,addPersonOrSystemBoundary:RVt,addContainer:BVt,addContainerBoundary:jVt,addComponent:FVt,addDeploymentNode:$Vt,popBoundaryParseStack:zVt,addRel:NVt,updateElStyle:qVt,updateRelStyle:HVt,updateLayoutConfig:VVt,autoWrap:D9,setWrap:eUt,getC4ShapeArray:kqe,getC4Shape:YVt,getC4ShapeKeys:XVt,getBoundaries:Eqe,getBoundarys:QVt,getCurrentBoundaryParse:KVt,getParentBoundaryParse:WVt,getRels:JVt,getTitle:ZVt,getC4Type:IVt,getC4ShapeInRow:UVt,getC4BoundaryInRow:GVt,setAccTitle:Bg,getAccTitle:Cp,getAccDescription:_p,setAccDescription:Sp,getConfig:()=>qt().c4,clear:function(){R3=[],Q4=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],j3="",Op="global",M9=[""],pR=[],M9=[""],Rbe="",jbe=!1,SQ=4,_Q=2},LINETYPE:{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},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(i){Rbe=Yf(i,qt())},setC4Type:OVt},AQ=(i,s)=>{const u=i.append("rect");if(u.attr("x",s.x),u.attr("y",s.y),u.attr("fill",s.fill),u.attr("stroke",s.stroke),u.attr("width",s.width),u.attr("height",s.height),s.name&&u.attr("name",s.name),s.rx!==void 0&&u.attr("rx",s.rx),s.ry!==void 0&&u.attr("ry",s.ry),s.attrs!==void 0)for(const d in s.attrs)u.attr(d,s.attrs[d]);return s.class!==void 0&&u.attr("class",s.class),u},Tqe=(i,s)=>{const u={x:s.startx,y:s.starty,width:s.stopx-s.startx,height:s.stopy-s.starty,fill:s.fill,stroke:s.stroke,class:"rect"};AQ(i,u).lower()},tUt=(i,s)=>{const u=s.text.replace(fD," "),d=i.append("text");d.attr("x",s.x),d.attr("y",s.y),d.attr("class","legend"),d.style("text-anchor",s.anchor),s.class!==void 0&&d.attr("class",s.class);const p=d.append("tspan");return p.attr("x",s.x+s.textMargin*2),p.text(u),d},nUt=(i,s,u,d)=>{const p=i.append("image");p.attr("x",s),p.attr("y",u);const v=p9.sanitizeUrl(d);p.attr("xlink:href",v)},rUt=(i,s,u,d)=>{const p=i.append("use");p.attr("x",s),p.attr("y",u);const v=p9.sanitizeUrl(d);p.attr("xlink:href",`#${v}`)},qC=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),zbe=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),qbe=function(i,s){return AQ(i,s)},Cqe=function(i,s,u,d,p,v){const b=i.append("image");b.attr("width",s),b.attr("height",u),b.attr("x",d),b.attr("y",p);let y=v.startsWith("data:image/png;base64")?v:p9.sanitizeUrl(v);b.attr("xlink:href",y)},iUt=(i,s,u)=>{const d=i.append("g");let p=0;for(let v of s){let b=v.textColor?v.textColor:"#444444",y=v.lineColor?v.lineColor:"#444444",T=v.offsetX?parseInt(v.offsetX):0,_=v.offsetY?parseInt(v.offsetY):0,A="";if(p===0){let R=d.append("line");R.attr("x1",v.startPoint.x),R.attr("y1",v.startPoint.y),R.attr("x2",v.endPoint.x),R.attr("y2",v.endPoint.y),R.attr("stroke-width","1"),R.attr("stroke",y),R.style("fill","none"),v.type!=="rel_b"&&R.attr("marker-end","url("+A+"#arrowhead)"),(v.type==="birel"||v.type==="rel_b")&&R.attr("marker-start","url("+A+"#arrowend)"),p=-1}else{let R=d.append("path");R.attr("fill","none").attr("stroke-width","1").attr("stroke",y).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",v.startPoint.x).replaceAll("starty",v.startPoint.y).replaceAll("controlx",v.startPoint.x+(v.endPoint.x-v.startPoint.x)/2-(v.endPoint.x-v.startPoint.x)/4).replaceAll("controly",v.startPoint.y+(v.endPoint.y-v.startPoint.y)/2).replaceAll("stopx",v.endPoint.x).replaceAll("stopy",v.endPoint.y)),v.type!=="rel_b"&&R.attr("marker-end","url("+A+"#arrowhead)"),(v.type==="birel"||v.type==="rel_b")&&R.attr("marker-start","url("+A+"#arrowend)")}let P=u.messageFont();F7(u)(v.label.text,d,Math.min(v.startPoint.x,v.endPoint.x)+Math.abs(v.endPoint.x-v.startPoint.x)/2+T,Math.min(v.startPoint.y,v.endPoint.y)+Math.abs(v.endPoint.y-v.startPoint.y)/2+_,v.label.width,v.label.height,{fill:b},P),v.techn&&v.techn.text!==""&&(P=u.messageFont(),F7(u)("["+v.techn.text+"]",d,Math.min(v.startPoint.x,v.endPoint.x)+Math.abs(v.endPoint.x-v.startPoint.x)/2+T,Math.min(v.startPoint.y,v.endPoint.y)+Math.abs(v.endPoint.y-v.startPoint.y)/2+u.messageFontSize+5+_,Math.max(v.label.width,v.techn.width),v.techn.height,{fill:b,"font-style":"italic"},P))}},sUt=function(i,s,u){const d=i.append("g");let p=s.bgColor?s.bgColor:"none",v=s.borderColor?s.borderColor:"#444444",b=s.fontColor?s.fontColor:"black",y={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};s.nodeType&&(y={"stroke-width":1});let T={x:s.x,y:s.y,fill:p,stroke:v,width:s.width,height:s.height,rx:2.5,ry:2.5,attrs:y};qbe(d,T);let _=u.boundaryFont();_.fontWeight="bold",_.fontSize=_.fontSize+2,_.fontColor=b,F7(u)(s.label.text,d,s.x,s.y+s.label.Y,s.width,s.height,{fill:"#444444"},_),s.type&&s.type.text!==""&&(_=u.boundaryFont(),_.fontColor=b,F7(u)(s.type.text,d,s.x,s.y+s.type.Y,s.width,s.height,{fill:"#444444"},_)),s.descr&&s.descr.text!==""&&(_=u.boundaryFont(),_.fontSize=_.fontSize-2,_.fontColor=b,F7(u)(s.descr.text,d,s.x,s.y+s.descr.Y,s.width,s.height,{fill:"#444444"},_))},aUt=function(i,s,u){var P;let d=s.bgColor?s.bgColor:u[s.typeC4Shape.text+"_bg_color"],p=s.borderColor?s.borderColor:u[s.typeC4Shape.text+"_border_color"],v=s.fontColor?s.fontColor:"#FFFFFF",b="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(s.typeC4Shape.text){case"person":b="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":b="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII=";break}const y=i.append("g");y.attr("class","person-man");const T=qC();switch(s.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":T.x=s.x,T.y=s.y,T.fill=d,T.width=s.width,T.height=s.height,T.stroke=p,T.rx=2.5,T.ry=2.5,T.attrs={"stroke-width":.5},qbe(y,T);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":y.append("path").attr("fill",d).attr("stroke-width","0.5").attr("stroke",p).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",s.x).replaceAll("starty",s.y).replaceAll("half",s.width/2).replaceAll("height",s.height)),y.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",p).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",s.x).replaceAll("starty",s.y).replaceAll("half",s.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":y.append("path").attr("fill",d).attr("stroke-width","0.5").attr("stroke",p).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",s.x).replaceAll("starty",s.y).replaceAll("width",s.width).replaceAll("half",s.height/2)),y.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",p).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",s.x+s.width).replaceAll("starty",s.y).replaceAll("half",s.height/2));break}let _=pUt(u,s.typeC4Shape.text);switch(y.append("text").attr("fill",v).attr("font-family",_.fontFamily).attr("font-size",_.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",s.typeC4Shape.width).attr("x",s.x+s.width/2-s.typeC4Shape.width/2).attr("y",s.y+s.typeC4Shape.Y).text("<<"+s.typeC4Shape.text+">>"),s.typeC4Shape.text){case"person":case"external_person":Cqe(y,48,48,s.x+s.width/2-24,s.y+s.image.Y,b);break}let A=u[s.typeC4Shape.text+"Font"]();return A.fontWeight="bold",A.fontSize=A.fontSize+2,A.fontColor=v,F7(u)(s.label.text,y,s.x,s.y+s.label.Y,s.width,s.height,{fill:v},A),A=u[s.typeC4Shape.text+"Font"](),A.fontColor=v,s.techn&&((P=s.techn)==null?void 0:P.text)!==""?F7(u)(s.techn.text,y,s.x,s.y+s.techn.Y,s.width,s.height,{fill:v,"font-style":"italic"},A):s.type&&s.type.text!==""&&F7(u)(s.type.text,y,s.x,s.y+s.type.Y,s.width,s.height,{fill:v,"font-style":"italic"},A),s.descr&&s.descr.text!==""&&(A=u.personFont(),A.fontColor=v,F7(u)(s.descr.text,y,s.x,s.y+s.descr.Y,s.width,s.height,{fill:v},A)),s.height},oUt=function(i){i.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")},cUt=function(i){i.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")},uUt=function(i){i.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")},lUt=function(i){i.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")},hUt=function(i){i.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")},fUt=function(i){i.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")},dUt=function(i){i.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)},gUt=function(i){const u=i.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);u.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"),u.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")},pUt=(i,s)=>({fontFamily:i[s+"FontFamily"],fontSize:i[s+"FontSize"],fontWeight:i[s+"FontWeight"]}),F7=function(){function i(p,v,b,y,T,_,A){const P=v.append("text").attr("x",b+T/2).attr("y",y+_/2+5).style("text-anchor","middle").text(p);d(P,A)}function s(p,v,b,y,T,_,A,P){const{fontSize:R,fontFamily:F,fontWeight:j}=P,K=p.split(ci.lineBreakRegex);for(let ee=0;ee=this.data.widthLimit||d>=this.data.widthLimit||this.nextData.cnt>Sqe)&&(u=this.nextData.startx+s.margin+$s.nextLinePaddingX,p=this.nextData.stopy+s.margin*2,this.nextData.stopx=d=u+s.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=v=p+s.height,this.nextData.cnt=1),s.x=u,s.y=p,this.updateVal(this.data,"startx",u,Math.min),this.updateVal(this.data,"starty",p,Math.min),this.updateVal(this.data,"stopx",d,Math.max),this.updateVal(this.data,"stopy",v,Math.max),this.updateVal(this.nextData,"startx",u,Math.min),this.updateVal(this.nextData,"starty",p,Math.min),this.updateVal(this.nextData,"stopx",d,Math.max),this.updateVal(this.nextData,"stopy",v,Math.max)}init(s){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},Vbe(s.db.getConfig())}bumpLastMargin(s){this.data.stopx+=s,this.data.stopy+=s}}const Vbe=function(i){id($s,i),i.fontFamily&&($s.personFontFamily=$s.systemFontFamily=$s.messageFontFamily=i.fontFamily),i.fontSize&&($s.personFontSize=$s.systemFontSize=$s.messageFontSize=i.fontSize),i.fontWeight&&($s.personFontWeight=$s.systemFontWeight=$s.messageFontWeight=i.fontWeight)},bR=(i,s)=>({fontFamily:i[s+"FontFamily"],fontSize:i[s+"FontSize"],fontWeight:i[s+"FontWeight"]}),DQ=i=>({fontFamily:i.boundaryFontFamily,fontSize:i.boundaryFontSize,fontWeight:i.boundaryFontWeight}),bUt=i=>({fontFamily:i.messageFontFamily,fontSize:i.messageFontSize,fontWeight:i.messageFontWeight});function $3(i,s,u,d,p){if(!s[i].width)if(u)s[i].text=vje(s[i].text,p,d),s[i].textLines=s[i].text.split(ci.lineBreakRegex).length,s[i].width=p,s[i].height=E2e(s[i].text,d);else{let v=s[i].text.split(ci.lineBreakRegex);s[i].textLines=v.length;let b=0;s[i].height=0,s[i].width=0;for(const y of v)s[i].width=Math.max(H4(y,d),s[i].width),b=E2e(y,d),s[i].height=s[i].height+b}}const Aqe=function(i,s,u){s.x=u.data.startx,s.y=u.data.starty,s.width=u.data.stopx-u.data.startx,s.height=u.data.stopy-u.data.starty,s.label.y=$s.c4ShapeMargin-35;let d=s.wrap&&$s.wrap,p=DQ($s);p.fontSize=p.fontSize+2,p.fontWeight="bold";let v=H4(s.label.text,p);$3("label",s,d,p,v),J4.drawBoundary(i,s,$s)},Lqe=function(i,s,u,d){let p=0;for(const v of d){p=0;const b=u[v];let y=bR($s,b.typeC4Shape.text);switch(y.fontSize=y.fontSize-2,b.typeC4Shape.width=H4("«"+b.typeC4Shape.text+"»",y),b.typeC4Shape.height=y.fontSize+2,b.typeC4Shape.Y=$s.c4ShapePadding,p=b.typeC4Shape.Y+b.typeC4Shape.height-4,b.image={width:0,height:0,Y:0},b.typeC4Shape.text){case"person":case"external_person":b.image.width=48,b.image.height=48,b.image.Y=p,p=b.image.Y+b.image.height;break}b.sprite&&(b.image.width=48,b.image.height=48,b.image.Y=p,p=b.image.Y+b.image.height);let T=b.wrap&&$s.wrap,_=$s.width-$s.c4ShapePadding*2,A=bR($s,b.typeC4Shape.text);if(A.fontSize=A.fontSize+2,A.fontWeight="bold",$3("label",b,T,A,_),b.label.Y=p+8,p=b.label.Y+b.label.height,b.type&&b.type.text!==""){b.type.text="["+b.type.text+"]";let F=bR($s,b.typeC4Shape.text);$3("type",b,T,F,_),b.type.Y=p+5,p=b.type.Y+b.type.height}else if(b.techn&&b.techn.text!==""){b.techn.text="["+b.techn.text+"]";let F=bR($s,b.techn.text);$3("techn",b,T,F,_),b.techn.Y=p+5,p=b.techn.Y+b.techn.height}let P=p,R=b.label.width;if(b.descr&&b.descr.text!==""){let F=bR($s,b.typeC4Shape.text);$3("descr",b,T,F,_),b.descr.Y=p+20,p=b.descr.Y+b.descr.height,R=Math.max(b.label.width,b.descr.width),P=p-b.descr.textLines*5}R=R+$s.c4ShapePadding,b.width=Math.max(b.width||$s.width,R,$s.width),b.height=Math.max(b.height||$s.height,P,$s.height),b.margin=b.margin||$s.c4ShapeMargin,i.insert(b),J4.drawC4Shape(s,b,$s)}i.bumpLastMargin($s.c4ShapeMargin)};let jv=class{constructor(s,u){this.x=s,this.y=u}},Mqe=function(i,s){let u=i.x,d=i.y,p=s.x,v=s.y,b=u+i.width/2,y=d+i.height/2,T=Math.abs(u-p),_=Math.abs(d-v),A=_/T,P=i.height/i.width,R=null;return d==v&&up?R=new jv(u,y):u==p&&dv&&(R=new jv(b,d)),u>p&&d=A?R=new jv(u,y+A*i.width/2):R=new jv(b-T/_*i.height/2,d+i.height):u=A?R=new jv(u+i.width,y+A*i.width/2):R=new jv(b+T/_*i.height/2,d+i.height):uv?P>=A?R=new jv(u+i.width,y-A*i.width/2):R=new jv(b+i.height/2*T/_,d):u>p&&d>v&&(P>=A?R=new jv(u,y-i.width/2*A):R=new jv(b-i.height/2*T/_,d)),R},mUt=function(i,s){let u={x:0,y:0};u.x=s.x+s.width/2,u.y=s.y+s.height/2;let d=Mqe(i,u);u.x=i.x+i.width/2,u.y=i.y+i.height/2;let p=Mqe(s,u);return{startPoint:d,endPoint:p}};const vUt=function(i,s,u,d){let p=0;for(let v of s){p=p+1;let b=v.wrap&&$s.wrap,y=bUt($s);d.db.getC4Type()==="C4Dynamic"&&(v.label.text=p+": "+v.label.text);let _=H4(v.label.text,y);$3("label",v,b,y,_),v.techn&&v.techn.text!==""&&(_=H4(v.techn.text,y),$3("techn",v,b,y,_)),v.descr&&v.descr.text!==""&&(_=H4(v.descr.text,y),$3("descr",v,b,y,_));let A=u(v.from),P=u(v.to),R=mUt(A,P);v.startPoint=R.startPoint,v.endPoint=R.endPoint}J4.drawRels(i,s,$s)};function Dqe(i,s,u,d,p){let v=new _qe(p);v.data.widthLimit=u.data.widthLimit/Math.min(Hbe,d.length);for(let[b,y]of d.entries()){let T=0;y.image={width:0,height:0,Y:0},y.sprite&&(y.image.width=48,y.image.height=48,y.image.Y=T,T=y.image.Y+y.image.height);let _=y.wrap&&$s.wrap,A=DQ($s);if(A.fontSize=A.fontSize+2,A.fontWeight="bold",$3("label",y,_,A,v.data.widthLimit),y.label.Y=T+8,T=y.label.Y+y.label.height,y.type&&y.type.text!==""){y.type.text="["+y.type.text+"]";let j=DQ($s);$3("type",y,_,j,v.data.widthLimit),y.type.Y=T+5,T=y.type.Y+y.type.height}if(y.descr&&y.descr.text!==""){let j=DQ($s);j.fontSize=j.fontSize-2,$3("descr",y,_,j,v.data.widthLimit),y.descr.Y=T+20,T=y.descr.Y+y.descr.height}if(b==0||b%Hbe===0){let j=u.data.startx+$s.diagramMarginX,K=u.data.stopy+$s.diagramMarginY+T;v.setData(j,j,K,K)}else{let j=v.data.stopx!==v.data.startx?v.data.stopx+$s.diagramMarginX:v.data.startx,K=v.data.starty;v.setData(j,j,K,K)}v.name=y.alias;let P=p.db.getC4ShapeArray(y.alias),R=p.db.getC4ShapeKeys(y.alias);R.length>0&&Lqe(v,i,P,R),s=y.alias;let F=p.db.getBoundarys(s);F.length>0&&Dqe(i,s,v,F,p),y.alias!=="global"&&Aqe(i,y,v),u.data.stopy=Math.max(v.data.stopy+$s.c4ShapeMargin,u.data.stopy),u.data.stopx=Math.max(v.data.stopx+$s.c4ShapeMargin,u.data.stopx),LQ=Math.max(LQ,u.data.stopx),MQ=Math.max(MQ,u.data.stopy)}}const Iqe={drawPersonOrSystemArray:Lqe,drawBoundary:Aqe,setConf:Vbe,draw:function(i,s,u,d){$s=qt().c4;const p=qt().securityLevel;let v;p==="sandbox"&&(v=Ir("#i"+s));const b=Ir(p==="sandbox"?v.nodes()[0].contentDocument.body:"body");let y=d.db;d.db.setWrap($s.wrap),Sqe=y.getC4ShapeInRow(),Hbe=y.getC4BoundaryInRow(),Xe.debug(`C:${JSON.stringify($s,null,2)}`);const T=p==="sandbox"?b.select(`[id="${s}"]`):Ir(`[id="${s}"]`);J4.insertComputerIcon(T),J4.insertDatabaseIcon(T),J4.insertClockIcon(T);let _=new _qe(d);_.setData($s.diagramMarginX,$s.diagramMarginX,$s.diagramMarginY,$s.diagramMarginY),_.data.widthLimit=screen.availWidth,LQ=$s.diagramMarginX,MQ=$s.diagramMarginY;const A=d.db.getTitle();let P=d.db.getBoundarys("");Dqe(T,"",_,P,d),J4.insertArrowHead(T),J4.insertArrowEnd(T),J4.insertArrowCrossHead(T),J4.insertArrowFilledHead(T),vUt(T,d.db.getRels(),d.db.getC4Shape,d),_.data.stopx=LQ,_.data.stopy=MQ;const R=_.data;let j=R.stopy-R.starty+2*$s.diagramMarginY;const ee=R.stopx-R.startx+2*$s.diagramMarginX;A&&T.append("text").text(A).attr("x",(R.stopx-R.startx)/2-4*$s.diagramMarginX).attr("y",R.starty+$s.diagramMarginY),Ng(T,j,ee,$s.useMaxWidth);const ie=A?60:0;T.attr("viewBox",R.startx-$s.diagramMarginX+" -"+($s.diagramMarginY+ie)+" "+ee+" "+(j+ie)),Xe.debug("models:",R)}},wUt=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:DVt,db:$be,renderer:Iqe,styles:i=>`.person { + stroke: ${i.personBorder}; + fill: ${i.personBkg}; + } +`,init:({c4:i,wrap:s})=>{Iqe.setConf(i),$be.setWrap(s)}}},Symbol.toStringTag,{value:"Module"}));var Ube=function(){var i=function($0,Wi,Bs,Qa){for(Bs=Bs||{},Qa=$0.length;Qa--;Bs[$0[Qa]]=Wi);return Bs},s=[1,4],u=[1,3],d=[1,5],p=[1,8,9,10,11,27,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],v=[2,2],b=[1,13],y=[1,14],T=[1,15],_=[1,16],A=[1,23],P=[1,25],R=[1,26],F=[1,27],j=[1,49],K=[1,48],ee=[1,29],ie=[1,30],oe=[1,31],pe=[1,32],be=[1,33],ae=[1,44],ne=[1,46],se=[1,42],de=[1,47],X=[1,43],ge=[1,50],W=[1,45],xe=[1,51],U=[1,52],Fe=[1,34],Pe=[1,35],je=[1,36],Ie=[1,37],Se=[1,57],Ce=[1,8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],ke=[1,61],Ke=[1,60],Ft=[1,62],Ne=[8,9,11,73,75],gn=[1,88],_t=[1,93],Et=[1,92],Gt=[1,89],ln=[1,85],xt=[1,91],Pt=[1,87],Qe=[1,94],Dt=[1,90],kt=[1,95],On=[1,86],ht=[8,9,10,11,73,75],zr=[8,9,10,11,44,73,75],yt=[8,9,10,11,29,42,44,46,48,50,52,54,56,58,61,63,65,66,68,73,75,86,99,102,103,106,108,111,112,113],ji=[8,9,11,42,58,73,75,86,99,102,103,106,108,111,112,113],xi=[42,58,86,99,102,103,106,108,111,112,113],Ma=[1,121],zs=[1,120],ao=[1,128],Tr=[1,142],Fn=[1,143],qn=[1,144],Un=[1,145],At=[1,130],wt=[1,132],on=[1,136],fn=[1,137],An=[1,138],oo=[1,139],jo=[1,140],$o=[1,141],Pa=[1,146],wo=[1,147],_s=[1,126],tl=[1,127],da=[1,134],j0=[1,129],pm=[1,133],Ml=[1,131],Xc=[8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],Bc=[1,149],ja=[8,9,11],Ou=[8,9,10,11,14,42,58,86,102,103,106,108,111,112,113],Sa=[1,169],Po=[1,165],Fc=[1,166],xa=[1,170],Ba=[1,167],ga=[1,168],kh=[75,113,116],lu=[8,9,10,11,12,14,27,29,32,42,58,73,81,82,83,84,85,86,87,102,106,108,111,112,113],o5=[10,103],Wh=[31,47,49,51,53,55,60,62,64,65,67,69,113,114,115],od=[1,235],Gd=[1,233],cd=[1,237],Kd=[1,231],$g=[1,232],as=[1,234],wn=[1,236],Zr=[1,238],Zi=[1,255],nu=[8,9,11,103],vu=[8,9,10,11,58,81,102,103,106,107,108,109],Dl={trace:function(){},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,link:39,node:40,styledVertex:41,AMP:42,vertex:43,STYLE_SEPARATOR:44,idString:45,DOUBLECIRCLESTART:46,DOUBLECIRCLEEND:47,PS:48,PE:49,"(-":50,"-)":51,STADIUMSTART:52,STADIUMEND:53,SUBROUTINESTART:54,SUBROUTINEEND:55,VERTEX_WITH_PROPS_START:56,"NODE_STRING[field]":57,COLON:58,"NODE_STRING[value]":59,PIPE:60,CYLINDERSTART:61,CYLINDEREND:62,DIAMOND_START:63,DIAMOND_STOP:64,TAGEND:65,TRAPSTART:66,TRAPEND:67,INVTRAPSTART:68,INVTRAPEND:69,linkStatement:70,arrowText:71,TESTSTR:72,START_LINK:73,edgeText:74,LINK:75,edgeTextToken:76,STR:77,MD_STR:78,textToken:79,keywords:80,STYLE:81,LINKSTYLE:82,CLASSDEF:83,CLASS:84,CLICK:85,DOWN:86,UP:87,textNoTagsToken:88,stylesOpt:89,"idString[vertex]":90,"idString[class]":91,CALLBACKNAME:92,CALLBACKARGS:93,HREF:94,LINK_TARGET:95,"STR[link]":96,"STR[tooltip]":97,alphaNum:98,DEFAULT:99,numList:100,INTERPOLATE:101,NUM:102,COMMA:103,style:104,styleComponent:105,NODE_STRING:106,UNIT:107,BRKT:108,PCT:109,idStringToken:110,MINUS:111,MULT:112,UNICODE_TEXT:113,TEXT:114,TAGSTART:115,EDGE_TEXT:116,alphaNumToken:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,$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",42:"AMP",44:"STYLE_SEPARATOR",46:"DOUBLECIRCLESTART",47:"DOUBLECIRCLEEND",48:"PS",49:"PE",50:"(-",51:"-)",52:"STADIUMSTART",53:"STADIUMEND",54:"SUBROUTINESTART",55:"SUBROUTINEEND",56:"VERTEX_WITH_PROPS_START",57:"NODE_STRING[field]",58:"COLON",59:"NODE_STRING[value]",60:"PIPE",61:"CYLINDERSTART",62:"CYLINDEREND",63:"DIAMOND_START",64:"DIAMOND_STOP",65:"TAGEND",66:"TRAPSTART",67:"TRAPEND",68:"INVTRAPSTART",69:"INVTRAPEND",72:"TESTSTR",73:"START_LINK",75:"LINK",77:"STR",78:"MD_STR",81:"STYLE",82:"LINKSTYLE",83:"CLASSDEF",84:"CLASS",85:"CLICK",86:"DOWN",87:"UP",90:"idString[vertex]",91:"idString[class]",92:"CALLBACKNAME",93:"CALLBACKARGS",94:"HREF",95:"LINK_TARGET",96:"STR[link]",97:"STR[tooltip]",99:"DEFAULT",101:"INTERPOLATE",102:"NUM",103:"COMMA",106:"NODE_STRING",107:"UNIT",108:"BRKT",109:"PCT",111:"MINUS",112:"MULT",113:"UNICODE_TEXT",114:"TEXT",115:"TAGSTART",116:"EDGE_TEXT",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"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],[20,3],[20,4],[20,2],[20,1],[40,1],[40,5],[41,1],[41,3],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,8],[43,4],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,4],[43,4],[43,1],[39,2],[39,3],[39,3],[39,1],[39,3],[74,1],[74,2],[74,1],[74,1],[70,1],[71,3],[30,1],[30,2],[30,1],[30,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,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],[100,1],[100,3],[89,1],[89,3],[104,1],[104,2],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[79,1],[79,1],[79,1],[79,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[76,1],[76,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[45,1],[45,2],[98,1],[98,2],[33,1],[33,1],[33,1],[33,1]],performAction:function(Wi,Bs,Qa,Bi,Nu,Ot,W3){var Kt=Ot.length-1;switch(Nu){case 2:this.$=[];break;case 3:(!Array.isArray(Ot[Kt])||Ot[Kt].length>0)&&Ot[Kt-1].push(Ot[Kt]),this.$=Ot[Kt-1];break;case 4:case 176:this.$=Ot[Kt];break;case 11:Bi.setDirection("TB"),this.$="TB";break;case 12:Bi.setDirection(Ot[Kt-1]),this.$=Ot[Kt-1];break;case 27:this.$=Ot[Kt-1].nodes;break;case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 33:this.$=Bi.addSubGraph(Ot[Kt-6],Ot[Kt-1],Ot[Kt-4]);break;case 34:this.$=Bi.addSubGraph(Ot[Kt-3],Ot[Kt-1],Ot[Kt-3]);break;case 35:this.$=Bi.addSubGraph(void 0,Ot[Kt-1],void 0);break;case 37:this.$=Ot[Kt].trim(),Bi.setAccTitle(this.$);break;case 38:case 39:this.$=Ot[Kt].trim(),Bi.setAccDescription(this.$);break;case 43:Bi.addLink(Ot[Kt-2].stmt,Ot[Kt],Ot[Kt-1]),this.$={stmt:Ot[Kt],nodes:Ot[Kt].concat(Ot[Kt-2].nodes)};break;case 44:Bi.addLink(Ot[Kt-3].stmt,Ot[Kt-1],Ot[Kt-2]),this.$={stmt:Ot[Kt-1],nodes:Ot[Kt-1].concat(Ot[Kt-3].nodes)};break;case 45:this.$={stmt:Ot[Kt-1],nodes:Ot[Kt-1]};break;case 46:this.$={stmt:Ot[Kt],nodes:Ot[Kt]};break;case 47:this.$=[Ot[Kt]];break;case 48:this.$=Ot[Kt-4].concat(Ot[Kt]);break;case 49:this.$=Ot[Kt];break;case 50:this.$=Ot[Kt-2],Bi.setClass(Ot[Kt-2],Ot[Kt]);break;case 51:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"square");break;case 52:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"doublecircle");break;case 53:this.$=Ot[Kt-5],Bi.addVertex(Ot[Kt-5],Ot[Kt-2],"circle");break;case 54:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"ellipse");break;case 55:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"stadium");break;case 56:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"subroutine");break;case 57:this.$=Ot[Kt-7],Bi.addVertex(Ot[Kt-7],Ot[Kt-1],"rect",void 0,void 0,void 0,Object.fromEntries([[Ot[Kt-5],Ot[Kt-3]]]));break;case 58:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"cylinder");break;case 59:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"round");break;case 60:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"diamond");break;case 61:this.$=Ot[Kt-5],Bi.addVertex(Ot[Kt-5],Ot[Kt-2],"hexagon");break;case 62:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"odd");break;case 63:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"trapezoid");break;case 64:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"inv_trapezoid");break;case 65:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"lean_right");break;case 66:this.$=Ot[Kt-3],Bi.addVertex(Ot[Kt-3],Ot[Kt-1],"lean_left");break;case 67:this.$=Ot[Kt],Bi.addVertex(Ot[Kt]);break;case 68:Ot[Kt-1].text=Ot[Kt],this.$=Ot[Kt-1];break;case 69:case 70:Ot[Kt-2].text=Ot[Kt-1],this.$=Ot[Kt-2];break;case 71:this.$=Ot[Kt];break;case 72:var z0=Bi.destructLink(Ot[Kt],Ot[Kt-2]);this.$={type:z0.type,stroke:z0.stroke,length:z0.length,text:Ot[Kt-1]};break;case 73:this.$={text:Ot[Kt],type:"text"};break;case 74:this.$={text:Ot[Kt-1].text+""+Ot[Kt],type:Ot[Kt-1].type};break;case 75:this.$={text:Ot[Kt],type:"string"};break;case 76:this.$={text:Ot[Kt],type:"markdown"};break;case 77:var z0=Bi.destructLink(Ot[Kt]);this.$={type:z0.type,stroke:z0.stroke,length:z0.length};break;case 78:this.$=Ot[Kt-1];break;case 79:this.$={text:Ot[Kt],type:"text"};break;case 80:this.$={text:Ot[Kt-1].text+""+Ot[Kt],type:Ot[Kt-1].type};break;case 81:this.$={text:Ot[Kt],type:"string"};break;case 82:case 97:this.$={text:Ot[Kt],type:"markdown"};break;case 94:this.$={text:Ot[Kt],type:"text"};break;case 95:this.$={text:Ot[Kt-1].text+""+Ot[Kt],type:Ot[Kt-1].type};break;case 96:this.$={text:Ot[Kt],type:"text"};break;case 98:this.$=Ot[Kt-4],Bi.addClass(Ot[Kt-2],Ot[Kt]);break;case 99:this.$=Ot[Kt-4],Bi.setClass(Ot[Kt-2],Ot[Kt]);break;case 100:case 108:this.$=Ot[Kt-1],Bi.setClickEvent(Ot[Kt-1],Ot[Kt]);break;case 101:case 109:this.$=Ot[Kt-3],Bi.setClickEvent(Ot[Kt-3],Ot[Kt-2]),Bi.setTooltip(Ot[Kt-3],Ot[Kt]);break;case 102:this.$=Ot[Kt-2],Bi.setClickEvent(Ot[Kt-2],Ot[Kt-1],Ot[Kt]);break;case 103:this.$=Ot[Kt-4],Bi.setClickEvent(Ot[Kt-4],Ot[Kt-3],Ot[Kt-2]),Bi.setTooltip(Ot[Kt-4],Ot[Kt]);break;case 104:this.$=Ot[Kt-2],Bi.setLink(Ot[Kt-2],Ot[Kt]);break;case 105:this.$=Ot[Kt-4],Bi.setLink(Ot[Kt-4],Ot[Kt-2]),Bi.setTooltip(Ot[Kt-4],Ot[Kt]);break;case 106:this.$=Ot[Kt-4],Bi.setLink(Ot[Kt-4],Ot[Kt-2],Ot[Kt]);break;case 107:this.$=Ot[Kt-6],Bi.setLink(Ot[Kt-6],Ot[Kt-4],Ot[Kt]),Bi.setTooltip(Ot[Kt-6],Ot[Kt-2]);break;case 110:this.$=Ot[Kt-1],Bi.setLink(Ot[Kt-1],Ot[Kt]);break;case 111:this.$=Ot[Kt-3],Bi.setLink(Ot[Kt-3],Ot[Kt-2]),Bi.setTooltip(Ot[Kt-3],Ot[Kt]);break;case 112:this.$=Ot[Kt-3],Bi.setLink(Ot[Kt-3],Ot[Kt-2],Ot[Kt]);break;case 113:this.$=Ot[Kt-5],Bi.setLink(Ot[Kt-5],Ot[Kt-4],Ot[Kt]),Bi.setTooltip(Ot[Kt-5],Ot[Kt-2]);break;case 114:this.$=Ot[Kt-4],Bi.addVertex(Ot[Kt-2],void 0,void 0,Ot[Kt]);break;case 115:this.$=Ot[Kt-4],Bi.updateLink([Ot[Kt-2]],Ot[Kt]);break;case 116:this.$=Ot[Kt-4],Bi.updateLink(Ot[Kt-2],Ot[Kt]);break;case 117:this.$=Ot[Kt-8],Bi.updateLinkInterpolate([Ot[Kt-6]],Ot[Kt-2]),Bi.updateLink([Ot[Kt-6]],Ot[Kt]);break;case 118:this.$=Ot[Kt-8],Bi.updateLinkInterpolate(Ot[Kt-6],Ot[Kt-2]),Bi.updateLink(Ot[Kt-6],Ot[Kt]);break;case 119:this.$=Ot[Kt-6],Bi.updateLinkInterpolate([Ot[Kt-4]],Ot[Kt]);break;case 120:this.$=Ot[Kt-6],Bi.updateLinkInterpolate(Ot[Kt-4],Ot[Kt]);break;case 121:case 123:this.$=[Ot[Kt]];break;case 122:case 124:Ot[Kt-2].push(Ot[Kt]),this.$=Ot[Kt-2];break;case 126:this.$=Ot[Kt-1]+Ot[Kt];break;case 174:this.$=Ot[Kt];break;case 175:this.$=Ot[Kt-1]+""+Ot[Kt];break;case 177:this.$=Ot[Kt-1]+""+Ot[Kt];break;case 178:this.$={stmt:"dir",value:"TB"};break;case 179:this.$={stmt:"dir",value:"BT"};break;case 180:this.$={stmt:"dir",value:"RL"};break;case 181:this.$={stmt:"dir",value:"LR"};break}},table:[{3:1,4:2,9:s,10:u,12:d},{1:[3]},i(p,v,{5:6}),{4:7,9:s,10:u,12:d},{4:8,9:s,10:u,12:d},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:b,9:y,10:T,11:_,20:17,22:18,23:19,24:20,25:21,26:22,27:A,33:24,34:P,36:R,38:F,40:28,41:38,42:j,43:39,45:40,58:K,81:ee,82:ie,83:oe,84:pe,85:be,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U,118:Fe,119:Pe,120:je,121:Ie},i(p,[2,9]),i(p,[2,10]),i(p,[2,11]),{8:[1,54],9:[1,55],10:Se,15:53,18:56},i(Ce,[2,3]),i(Ce,[2,4]),i(Ce,[2,5]),i(Ce,[2,6]),i(Ce,[2,7]),i(Ce,[2,8]),{8:ke,9:Ke,11:Ft,21:58,39:59,70:63,73:[1,64],75:[1,65]},{8:ke,9:Ke,11:Ft,21:66},{8:ke,9:Ke,11:Ft,21:67},{8:ke,9:Ke,11:Ft,21:68},{8:ke,9:Ke,11:Ft,21:69},{8:ke,9:Ke,11:Ft,21:70},{8:ke,9:Ke,10:[1,71],11:Ft,21:72},i(Ce,[2,36]),{35:[1,73]},{37:[1,74]},i(Ce,[2,39]),i(Ne,[2,46],{18:75,10:Se}),{10:[1,76]},{10:[1,77]},{10:[1,78]},{10:[1,79]},{14:gn,42:_t,58:Et,77:[1,83],86:Gt,92:[1,80],94:[1,81],98:82,102:ln,103:xt,106:Pt,108:Qe,111:Dt,112:kt,113:On,117:84},i(Ce,[2,178]),i(Ce,[2,179]),i(Ce,[2,180]),i(Ce,[2,181]),i(ht,[2,47]),i(ht,[2,49],{44:[1,96]}),i(zr,[2,67],{110:109,29:[1,97],42:j,46:[1,98],48:[1,99],50:[1,100],52:[1,101],54:[1,102],56:[1,103],58:K,61:[1,104],63:[1,105],65:[1,106],66:[1,107],68:[1,108],86:ae,99:ne,102:se,103:de,106:X,108:ge,111:W,112:xe,113:U}),i(yt,[2,174]),i(yt,[2,135]),i(yt,[2,136]),i(yt,[2,137]),i(yt,[2,138]),i(yt,[2,139]),i(yt,[2,140]),i(yt,[2,141]),i(yt,[2,142]),i(yt,[2,143]),i(yt,[2,144]),i(yt,[2,145]),i(p,[2,12]),i(p,[2,18]),i(p,[2,19]),{9:[1,110]},i(ji,[2,26],{18:111,10:Se}),i(Ce,[2,27]),{40:112,41:38,42:j,43:39,45:40,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U},i(Ce,[2,40]),i(Ce,[2,41]),i(Ce,[2,42]),i(xi,[2,71],{71:113,60:[1,115],72:[1,114]}),{74:116,76:117,77:[1,118],78:[1,119],113:Ma,116:zs},i([42,58,60,72,86,99,102,103,106,108,111,112,113],[2,77]),i(Ce,[2,28]),i(Ce,[2,29]),i(Ce,[2,30]),i(Ce,[2,31]),i(Ce,[2,32]),{10:ao,12:Tr,14:Fn,27:qn,28:122,32:Un,42:At,58:wt,73:on,77:[1,124],78:[1,125],80:135,81:fn,82:An,83:oo,84:jo,85:$o,86:Pa,87:wo,88:123,102:_s,106:tl,108:da,111:j0,112:pm,113:Ml},i(Xc,v,{5:148}),i(Ce,[2,37]),i(Ce,[2,38]),i(Ne,[2,45],{42:Bc}),{42:j,45:150,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U},{99:[1,151],100:152,102:[1,153]},{42:j,45:154,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U},{42:j,45:155,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U},i(ja,[2,100],{10:[1,156],93:[1,157]}),{77:[1,158]},i(ja,[2,108],{117:160,10:[1,159],14:gn,42:_t,58:Et,86:Gt,102:ln,103:xt,106:Pt,108:Qe,111:Dt,112:kt,113:On}),i(ja,[2,110],{10:[1,161]}),i(Ou,[2,176]),i(Ou,[2,163]),i(Ou,[2,164]),i(Ou,[2,165]),i(Ou,[2,166]),i(Ou,[2,167]),i(Ou,[2,168]),i(Ou,[2,169]),i(Ou,[2,170]),i(Ou,[2,171]),i(Ou,[2,172]),i(Ou,[2,173]),{42:j,45:162,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U},{30:163,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:171,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:173,48:[1,172],65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:174,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:175,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:176,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{106:[1,177]},{30:178,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:179,63:[1,180],65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:181,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:182,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{30:183,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},i(yt,[2,175]),i(p,[2,20]),i(ji,[2,25]),i(Ne,[2,43],{18:184,10:Se}),i(xi,[2,68],{10:[1,185]}),{10:[1,186]},{30:187,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{75:[1,188],76:189,113:Ma,116:zs},i(kh,[2,73]),i(kh,[2,75]),i(kh,[2,76]),i(kh,[2,161]),i(kh,[2,162]),{8:ke,9:Ke,10:ao,11:Ft,12:Tr,14:Fn,21:191,27:qn,29:[1,190],32:Un,42:At,58:wt,73:on,80:135,81:fn,82:An,83:oo,84:jo,85:$o,86:Pa,87:wo,88:192,102:_s,106:tl,108:da,111:j0,112:pm,113:Ml},i(lu,[2,94]),i(lu,[2,96]),i(lu,[2,97]),i(lu,[2,150]),i(lu,[2,151]),i(lu,[2,152]),i(lu,[2,153]),i(lu,[2,154]),i(lu,[2,155]),i(lu,[2,156]),i(lu,[2,157]),i(lu,[2,158]),i(lu,[2,159]),i(lu,[2,160]),i(lu,[2,83]),i(lu,[2,84]),i(lu,[2,85]),i(lu,[2,86]),i(lu,[2,87]),i(lu,[2,88]),i(lu,[2,89]),i(lu,[2,90]),i(lu,[2,91]),i(lu,[2,92]),i(lu,[2,93]),{6:11,7:12,8:b,9:y,10:T,11:_,20:17,22:18,23:19,24:20,25:21,26:22,27:A,32:[1,193],33:24,34:P,36:R,38:F,40:28,41:38,42:j,43:39,45:40,58:K,81:ee,82:ie,83:oe,84:pe,85:be,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U,118:Fe,119:Pe,120:je,121:Ie},{10:Se,18:194},{10:[1,195],42:j,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:109,111:W,112:xe,113:U},{10:[1,196]},{10:[1,197],103:[1,198]},i(o5,[2,121]),{10:[1,199],42:j,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:109,111:W,112:xe,113:U},{10:[1,200],42:j,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:109,111:W,112:xe,113:U},{77:[1,201]},i(ja,[2,102],{10:[1,202]}),i(ja,[2,104],{10:[1,203]}),{77:[1,204]},i(Ou,[2,177]),{77:[1,205],95:[1,206]},i(ht,[2,50],{110:109,42:j,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,111:W,112:xe,113:U}),{31:[1,207],65:Sa,79:208,113:xa,114:Ba,115:ga},i(Wh,[2,79]),i(Wh,[2,81]),i(Wh,[2,82]),i(Wh,[2,146]),i(Wh,[2,147]),i(Wh,[2,148]),i(Wh,[2,149]),{47:[1,209],65:Sa,79:208,113:xa,114:Ba,115:ga},{30:210,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{49:[1,211],65:Sa,79:208,113:xa,114:Ba,115:ga},{51:[1,212],65:Sa,79:208,113:xa,114:Ba,115:ga},{53:[1,213],65:Sa,79:208,113:xa,114:Ba,115:ga},{55:[1,214],65:Sa,79:208,113:xa,114:Ba,115:ga},{58:[1,215]},{62:[1,216],65:Sa,79:208,113:xa,114:Ba,115:ga},{64:[1,217],65:Sa,79:208,113:xa,114:Ba,115:ga},{30:218,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},{31:[1,219],65:Sa,79:208,113:xa,114:Ba,115:ga},{65:Sa,67:[1,220],69:[1,221],79:208,113:xa,114:Ba,115:ga},{65:Sa,67:[1,223],69:[1,222],79:208,113:xa,114:Ba,115:ga},i(Ne,[2,44],{42:Bc}),i(xi,[2,70]),i(xi,[2,69]),{60:[1,224],65:Sa,79:208,113:xa,114:Ba,115:ga},i(xi,[2,72]),i(kh,[2,74]),{30:225,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},i(Xc,v,{5:226}),i(lu,[2,95]),i(Ce,[2,35]),{41:227,42:j,43:39,45:40,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U},{10:od,58:Gd,81:cd,89:228,102:Kd,104:229,105:230,106:$g,107:as,108:wn,109:Zr},{10:od,58:Gd,81:cd,89:239,101:[1,240],102:Kd,104:229,105:230,106:$g,107:as,108:wn,109:Zr},{10:od,58:Gd,81:cd,89:241,101:[1,242],102:Kd,104:229,105:230,106:$g,107:as,108:wn,109:Zr},{102:[1,243]},{10:od,58:Gd,81:cd,89:244,102:Kd,104:229,105:230,106:$g,107:as,108:wn,109:Zr},{42:j,45:245,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U},i(ja,[2,101]),{77:[1,246]},{77:[1,247],95:[1,248]},i(ja,[2,109]),i(ja,[2,111],{10:[1,249]}),i(ja,[2,112]),i(zr,[2,51]),i(Wh,[2,80]),i(zr,[2,52]),{49:[1,250],65:Sa,79:208,113:xa,114:Ba,115:ga},i(zr,[2,59]),i(zr,[2,54]),i(zr,[2,55]),i(zr,[2,56]),{106:[1,251]},i(zr,[2,58]),i(zr,[2,60]),{64:[1,252],65:Sa,79:208,113:xa,114:Ba,115:ga},i(zr,[2,62]),i(zr,[2,63]),i(zr,[2,65]),i(zr,[2,64]),i(zr,[2,66]),i([10,42,58,86,99,102,103,106,108,111,112,113],[2,78]),{31:[1,253],65:Sa,79:208,113:xa,114:Ba,115:ga},{6:11,7:12,8:b,9:y,10:T,11:_,20:17,22:18,23:19,24:20,25:21,26:22,27:A,32:[1,254],33:24,34:P,36:R,38:F,40:28,41:38,42:j,43:39,45:40,58:K,81:ee,82:ie,83:oe,84:pe,85:be,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U,118:Fe,119:Pe,120:je,121:Ie},i(ht,[2,48]),i(ja,[2,114],{103:Zi}),i(nu,[2,123],{105:256,10:od,58:Gd,81:cd,102:Kd,106:$g,107:as,108:wn,109:Zr}),i(vu,[2,125]),i(vu,[2,127]),i(vu,[2,128]),i(vu,[2,129]),i(vu,[2,130]),i(vu,[2,131]),i(vu,[2,132]),i(vu,[2,133]),i(vu,[2,134]),i(ja,[2,115],{103:Zi}),{10:[1,257]},i(ja,[2,116],{103:Zi}),{10:[1,258]},i(o5,[2,122]),i(ja,[2,98],{103:Zi}),i(ja,[2,99],{110:109,42:j,58:K,86:ae,99:ne,102:se,103:de,106:X,108:ge,111:W,112:xe,113:U}),i(ja,[2,103]),i(ja,[2,105],{10:[1,259]}),i(ja,[2,106]),{95:[1,260]},{49:[1,261]},{60:[1,262]},{64:[1,263]},{8:ke,9:Ke,11:Ft,21:264},i(Ce,[2,34]),{10:od,58:Gd,81:cd,102:Kd,104:265,105:230,106:$g,107:as,108:wn,109:Zr},i(vu,[2,126]),{14:gn,42:_t,58:Et,86:Gt,98:266,102:ln,103:xt,106:Pt,108:Qe,111:Dt,112:kt,113:On,117:84},{14:gn,42:_t,58:Et,86:Gt,98:267,102:ln,103:xt,106:Pt,108:Qe,111:Dt,112:kt,113:On,117:84},{95:[1,268]},i(ja,[2,113]),i(zr,[2,53]),{30:269,65:Sa,77:Po,78:Fc,79:164,113:xa,114:Ba,115:ga},i(zr,[2,61]),i(Xc,v,{5:270}),i(nu,[2,124],{105:256,10:od,58:Gd,81:cd,102:Kd,106:$g,107:as,108:wn,109:Zr}),i(ja,[2,119],{117:160,10:[1,271],14:gn,42:_t,58:Et,86:Gt,102:ln,103:xt,106:Pt,108:Qe,111:Dt,112:kt,113:On}),i(ja,[2,120],{117:160,10:[1,272],14:gn,42:_t,58:Et,86:Gt,102:ln,103:xt,106:Pt,108:Qe,111:Dt,112:kt,113:On}),i(ja,[2,107]),{31:[1,273],65:Sa,79:208,113:xa,114:Ba,115:ga},{6:11,7:12,8:b,9:y,10:T,11:_,20:17,22:18,23:19,24:20,25:21,26:22,27:A,32:[1,274],33:24,34:P,36:R,38:F,40:28,41:38,42:j,43:39,45:40,58:K,81:ee,82:ie,83:oe,84:pe,85:be,86:ae,99:ne,102:se,103:de,106:X,108:ge,110:41,111:W,112:xe,113:U,118:Fe,119:Pe,120:je,121:Ie},{10:od,58:Gd,81:cd,89:275,102:Kd,104:229,105:230,106:$g,107:as,108:wn,109:Zr},{10:od,58:Gd,81:cd,89:276,102:Kd,104:229,105:230,106:$g,107:as,108:wn,109:Zr},i(zr,[2,57]),i(Ce,[2,33]),i(ja,[2,117],{103:Zi}),i(ja,[2,118],{103:Zi})],defaultActions:{},parseError:function(Wi,Bs){if(Bs.recoverable)this.trace(Wi);else{var Qa=new Error(Wi);throw Qa.hash=Bs,Qa}},parse:function(Wi){var Bs=this,Qa=[0],Bi=[],Nu=[null],Ot=[],W3=this.table,Kt="",z0=0,Bp=0,Y3=2,$9=1,c5=Ot.slice.call(arguments,1),Eh=Object.create(this.lexer),zg={yy:{}};for(var bm in this.yy)Object.prototype.hasOwnProperty.call(this.yy,bm)&&(zg.yy[bm]=this.yy[bm]);Eh.setInput(Wi,zg.yy),zg.yy.lexer=Eh,zg.yy.parser=this,typeof Eh.yylloc>"u"&&(Eh.yylloc={});var z9=Eh.yylloc;Ot.push(z9);var mm=Eh.options&&Eh.options.ranges;typeof zg.yy.parseError=="function"?this.parseError=zg.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function u5(){var Fp;return Fp=Bi.pop()||Eh.lex()||$9,typeof Fp!="number"&&(Fp instanceof Array&&(Bi=Fp,Fp=Bi.pop()),Fp=Bs.symbols_[Fp]||Fp),Fp}for(var y1,ud,ld,q9,Vv={},Y7,G2,X7,l5;;){if(ud=Qa[Qa.length-1],this.defaultActions[ud]?ld=this.defaultActions[ud]:((y1===null||typeof y1>"u")&&(y1=u5()),ld=W3[ud]&&W3[ud][y1]),typeof ld>"u"||!ld.length||!ld[0]){var X3="";l5=[];for(Y7 in W3[ud])this.terminals_[Y7]&&Y7>Y3&&l5.push("'"+this.terminals_[Y7]+"'");Eh.showPosition?X3="Parse error on line "+(z0+1)+`: +`+Eh.showPosition()+` +Expecting `+l5.join(", ")+", got '"+(this.terminals_[y1]||y1)+"'":X3="Parse error on line "+(z0+1)+": Unexpected "+(y1==$9?"end of input":"'"+(this.terminals_[y1]||y1)+"'"),this.parseError(X3,{text:Eh.match,token:this.terminals_[y1]||y1,line:Eh.yylineno,loc:z9,expected:l5})}if(ld[0]instanceof Array&&ld.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ud+", token: "+y1);switch(ld[0]){case 1:Qa.push(y1),Nu.push(Eh.yytext),Ot.push(Eh.yylloc),Qa.push(ld[1]),y1=null,Bp=Eh.yyleng,Kt=Eh.yytext,z0=Eh.yylineno,z9=Eh.yylloc;break;case 2:if(G2=this.productions_[ld[1]][1],Vv.$=Nu[Nu.length-G2],Vv._$={first_line:Ot[Ot.length-(G2||1)].first_line,last_line:Ot[Ot.length-1].last_line,first_column:Ot[Ot.length-(G2||1)].first_column,last_column:Ot[Ot.length-1].last_column},mm&&(Vv._$.range=[Ot[Ot.length-(G2||1)].range[0],Ot[Ot.length-1].range[1]]),q9=this.performAction.apply(Vv,[Kt,Bp,z0,zg.yy,ld[1],Nu,Ot].concat(c5)),typeof q9<"u")return q9;G2&&(Qa=Qa.slice(0,-1*G2*2),Nu=Nu.slice(0,-1*G2),Ot=Ot.slice(0,-1*G2)),Qa.push(this.productions_[ld[1]][0]),Nu.push(Vv.$),Ot.push(Vv._$),X7=W3[Qa[Qa.length-2]][Qa[Qa.length-1]],Qa.push(X7);break;case 3:return!0}}return!0}},Yh=function(){var $0={EOF:1,parseError:function(Bs,Qa){if(this.yy.parser)this.yy.parser.parseError(Bs,Qa);else throw new Error(Bs)},setInput:function(Wi,Bs){return this.yy=Bs||this.yy||{},this._input=Wi,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},input:function(){var Wi=this._input[0];this.yytext+=Wi,this.yyleng++,this.offset++,this.match+=Wi,this.matched+=Wi;var Bs=Wi.match(/(?:\r\n?|\n).*/g);return Bs?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Wi},unput:function(Wi){var Bs=Wi.length,Qa=Wi.split(/(?:\r\n?|\n)/g);this._input=Wi+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Bs),this.offset-=Bs;var Bi=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),Qa.length-1&&(this.yylineno-=Qa.length-1);var Nu=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:Qa?(Qa.length===Bi.length?this.yylloc.first_column:0)+Bi[Bi.length-Qa.length].length-Qa[0].length:this.yylloc.first_column-Bs},this.options.ranges&&(this.yylloc.range=[Nu[0],Nu[0]+this.yyleng-Bs]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(Wi){this.unput(this.match.slice(Wi))},pastInput:function(){var Wi=this.matched.substr(0,this.matched.length-this.match.length);return(Wi.length>20?"...":"")+Wi.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var Wi=this.match;return Wi.length<20&&(Wi+=this._input.substr(0,20-Wi.length)),(Wi.substr(0,20)+(Wi.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var Wi=this.pastInput(),Bs=new Array(Wi.length+1).join("-");return Wi+this.upcomingInput()+` +`+Bs+"^"},test_match:function(Wi,Bs){var Qa,Bi,Nu;if(this.options.backtrack_lexer&&(Nu={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&&(Nu.yylloc.range=this.yylloc.range.slice(0))),Bi=Wi[0].match(/(?:\r\n?|\n).*/g),Bi&&(this.yylineno+=Bi.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Bi?Bi[Bi.length-1].length-Bi[Bi.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+Wi[0].length},this.yytext+=Wi[0],this.match+=Wi[0],this.matches=Wi,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(Wi[0].length),this.matched+=Wi[0],Qa=this.performAction.call(this,this.yy,this,Bs,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Qa)return Qa;if(this._backtrack){for(var Ot in Nu)this[Ot]=Nu[Ot];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Wi,Bs,Qa,Bi;this._more||(this.yytext="",this.match="");for(var Nu=this._currentRules(),Ot=0;OtBs[0].length)){if(Bs=Qa,Bi=Ot,this.options.backtrack_lexer){if(Wi=this.test_match(Qa,Nu[Ot]),Wi!==!1)return Wi;if(this._backtrack){Bs=!1;continue}else return!1}else if(!this.options.flex)break}return Bs?(Wi=this.test_match(Bs,Nu[Bi]),Wi!==!1?Wi:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var Bs=this.next();return Bs||this.lex()},begin:function(Bs){this.conditionStack.push(Bs)},popState:function(){var Bs=this.conditionStack.length-1;return Bs>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(Bs){return Bs=this.conditionStack.length-1-Math.abs(Bs||0),Bs>=0?this.conditionStack[Bs]:"INITIAL"},pushState:function(Bs){this.begin(Bs)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(Bs,Qa,Bi,Nu){switch(Bi){case 0:return this.begin("acc_title"),34;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),36;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:this.begin("callbackname");break;case 8:this.popState();break;case 9:this.popState(),this.begin("callbackargs");break;case 10:return 92;case 11:this.popState();break;case 12:return 93;case 13:return"MD_STR";case 14:this.popState();break;case 15:this.begin("md_string");break;case 16:return"STR";case 17:this.popState();break;case 18:this.pushState("string");break;case 19:return 81;case 20:return 99;case 21:return 82;case 22:return 101;case 23:return 83;case 24:return 84;case 25:return 94;case 26:this.begin("click");break;case 27:this.popState();break;case 28:return 85;case 29:return Bs.lex.firstGraph()&&this.begin("dir"),12;case 30:return Bs.lex.firstGraph()&&this.begin("dir"),12;case 31:return Bs.lex.firstGraph()&&this.begin("dir"),12;case 32:return 27;case 33:return 32;case 34:return 95;case 35:return 95;case 36:return 95;case 37:return 95;case 38:return this.popState(),13;case 39:return this.popState(),14;case 40:return this.popState(),14;case 41:return this.popState(),14;case 42:return this.popState(),14;case 43:return this.popState(),14;case 44:return this.popState(),14;case 45:return this.popState(),14;case 46:return this.popState(),14;case 47:return this.popState(),14;case 48:return this.popState(),14;case 49:return 118;case 50:return 119;case 51:return 120;case 52:return 121;case 53:return 102;case 54:return 108;case 55:return 44;case 56:return 58;case 57:return 42;case 58:return 8;case 59:return 103;case 60:return 112;case 61:return this.popState(),75;case 62:return this.pushState("edgeText"),73;case 63:return 116;case 64:return this.popState(),75;case 65:return this.pushState("thickEdgeText"),73;case 66:return 116;case 67:return this.popState(),75;case 68:return this.pushState("dottedEdgeText"),73;case 69:return 116;case 70:return 75;case 71:return this.popState(),51;case 72:return"TEXT";case 73:return this.pushState("ellipseText"),50;case 74:return this.popState(),53;case 75:return this.pushState("text"),52;case 76:return this.popState(),55;case 77:return this.pushState("text"),54;case 78:return 56;case 79:return this.pushState("text"),65;case 80:return this.popState(),62;case 81:return this.pushState("text"),61;case 82:return this.popState(),47;case 83:return this.pushState("text"),46;case 84:return this.popState(),67;case 85:return this.popState(),69;case 86:return 114;case 87:return this.pushState("trapText"),66;case 88:return this.pushState("trapText"),68;case 89:return 115;case 90:return 65;case 91:return 87;case 92:return"SEP";case 93:return 86;case 94:return 112;case 95:return 108;case 96:return 42;case 97:return 106;case 98:return 111;case 99:return 113;case 100:return this.popState(),60;case 101:return this.pushState("text"),60;case 102:return this.popState(),49;case 103:return this.pushState("text"),48;case 104:return this.popState(),31;case 105:return this.pushState("text"),29;case 106:return this.popState(),64;case 107:return this.pushState("text"),63;case 108:return"TEXT";case 109:return"QUOTE";case 110:return 9;case 111:return 10;case 112:return 11}},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]*)/,/^(?:[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:{callbackargs:{rules:[11,12,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},callbackname:{rules:[8,9,10,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},href:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},click:{rules:[15,18,27,28,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dottedEdgeText:{rules:[15,18,67,69,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},thickEdgeText:{rules:[15,18,64,66,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},edgeText:{rules:[15,18,61,63,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},trapText:{rules:[15,18,70,73,75,77,81,83,84,85,86,87,88,101,103,105,107],inclusive:!1},ellipseText:{rules:[15,18,70,71,72,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},text:{rules:[15,18,70,73,74,75,76,77,80,81,82,83,87,88,100,101,102,103,104,105,106,107,108],inclusive:!1},vertex:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dir:{rules:[15,18,38,39,40,41,42,43,44,45,46,47,48,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr_multiline:{rules:[5,6,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr:{rules:[3,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_title:{rules:[1,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},md_string:{rules:[13,14,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},string:{rules:[15,16,17,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},INITIAL:{rules:[0,2,4,7,15,18,19,20,21,22,23,24,25,26,29,30,31,32,33,34,35,36,37,49,50,51,52,53,54,55,56,57,58,59,60,61,62,64,65,67,68,70,73,75,77,78,79,81,83,87,88,89,90,91,92,93,94,95,96,97,98,99,101,103,105,107,109,110,111,112],inclusive:!0}}};return $0}();Dl.lexer=Yh;function w1(){this.yy={}}return w1.prototype=Dl,Dl.Parser=w1,new w1}();Ube.parser=Ube;const Gbe=Ube,yUt="flowchart-";let Oqe=0,BD=qt(),oh={},z3=[],FD={},R7=[],IQ={},OQ={},NQ=0,Kbe=!0,$v,PQ,BQ=[];const FQ=i=>ci.sanitizeText(i,BD),mR=function(i){const s=Object.keys(oh);for(const u of s)if(oh[u].id===i)return oh[u].domId;return i},Nqe=function(i,s,u,d,p,v,b={}){let y,T=i;T!==void 0&&T.trim().length!==0&&(oh[T]===void 0&&(oh[T]={id:T,labelType:"text",domId:yUt+T+"-"+Oqe,styles:[],classes:[]}),Oqe++,s!==void 0?(BD=qt(),y=FQ(s.text.trim()),oh[T].labelType=s.type,y[0]==='"'&&y[y.length-1]==='"'&&(y=y.substring(1,y.length-1)),oh[T].text=y):oh[T].text===void 0&&(oh[T].text=i),u!==void 0&&(oh[T].type=u),d!=null&&d.forEach(function(_){oh[T].styles.push(_)}),p!=null&&p.forEach(function(_){oh[T].classes.push(_)}),v!==void 0&&(oh[T].dir=v),oh[T].props===void 0?oh[T].props=b:b!==void 0&&Object.assign(oh[T].props,b))},Pqe=function(i,s,u){const v={start:i,end:s,type:void 0,text:"",labelType:"text"};Xe.info("abc78 Got edge...",v);const b=u.text;if(b!==void 0&&(v.text=FQ(b.text.trim()),v.text[0]==='"'&&v.text[v.text.length-1]==='"'&&(v.text=v.text.substring(1,v.text.length-1)),v.labelType=b.type),u!==void 0&&(v.type=u.type,v.stroke=u.stroke,v.length=u.length),(v==null?void 0:v.length)>10&&(v.length=10),z3.length<(BD.maxEdges??500))Xe.info("abc78 pushing edge..."),z3.push(v);else throw new Error(`Edge limit exceeded. ${z3.length} edges found, but the limit is ${BD.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.`)},Bqe=function(i,s,u){Xe.info("addLink (abc78)",i,s,u);let d,p;for(d=0;d=z3.length)throw new Error(`The index ${u} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${z3.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);u==="default"?z3.defaultStyle=s:(Ao.isSubstringInArray("fill",s)===-1&&s.push("fill:none"),z3[u].style=s)})},jqe=function(i,s){i.split(",").forEach(function(u){FD[u]===void 0&&(FD[u]={id:u,styles:[],textStyles:[]}),s!=null&&s.forEach(function(d){if(d.match("color")){const p=d.replace("fill","bgFill").replace("color","fill");FD[u].textStyles.push(p)}FD[u].styles.push(d)})})},$qe=function(i){$v=i,$v.match(/.*/)&&($v="LR"),$v.match(/.*v/)&&($v="TB"),$v==="TD"&&($v="TB")},RQ=function(i,s){i.split(",").forEach(function(u){let d=u;oh[d]!==void 0&&oh[d].classes.push(s),IQ[d]!==void 0&&IQ[d].classes.push(s)})},xUt=function(i,s){i.split(",").forEach(function(u){s!==void 0&&(OQ[PQ==="gen-1"?mR(u):u]=FQ(s))})},kUt=function(i,s,u){let d=mR(i);if(qt().securityLevel!=="loose"||s===void 0)return;let p=[];if(typeof u=="string"){p=u.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let v=0;v")),p.classed("hover",!0)}).on("mouseout",function(){s.transition().duration(500).style("opacity",0),Ir(this).classed("hover",!1)})};BQ.push(Yqe);const Xqe=function(i="gen-1"){oh={},FD={},z3=[],BQ=[Yqe],R7=[],IQ={},NQ=0,OQ={},Kbe=!0,PQ=i,BD=qt(),Pg()},Qqe=i=>{PQ=i||"gen-2"},Jqe=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},Zqe=function(i,s,u){let d=i.text.trim(),p=u.text;i===u&&u.text.match(/\s/)&&(d=void 0);function v(A){const P={boolean:{},number:{},string:{}},R=[];let F;return{nodeList:A.filter(function(K){const ee=typeof K;return K.stmt&&K.stmt==="dir"?(F=K.value,!1):K.trim()===""?!1:ee in P?P[ee].hasOwnProperty(K)?!1:P[ee][K]=!0:R.includes(K)?!1:R.push(K)}),dir:F}}let b=[];const{nodeList:y,dir:T}=v(b.concat.apply(b,s));if(b=y,PQ==="gen-1")for(let A=0;A2e3)return;if(eHe[vR]=s,R7[s].id===i)return{result:!0,count:0};let d=0,p=1;for(;d=0){const b=tHe(i,v);if(b.result)return{result:!0,count:p+b.count};p=p+b.count}d=d+1}return{result:!1,count:p}},nHe=function(i){return eHe[i]},rHe=function(){vR=-1,R7.length>0&&tHe("none",R7.length-1)},iHe=function(){return R7},sHe=()=>Kbe?(Kbe=!1,!0):!1,TUt=i=>{let s=i.trim(),u="arrow_open";switch(s[0]){case"<":u="arrow_point",s=s.slice(1);break;case"x":u="arrow_cross",s=s.slice(1);break;case"o":u="arrow_circle",s=s.slice(1);break}let d="normal";return s.includes("=")&&(d="thick"),s.includes(".")&&(d="dotted"),{type:u,stroke:d}},CUt=(i,s)=>{const u=s.length;let d=0;for(let p=0;p{const s=i.trim();let u=s.slice(0,-1),d="arrow_open";switch(s.slice(-1)){case"x":d="arrow_cross",s[0]==="x"&&(d="double_"+d,u=u.slice(1));break;case">":d="arrow_point",s[0]==="<"&&(d="double_"+d,u=u.slice(1));break;case"o":d="arrow_circle",s[0]==="o"&&(d="double_"+d,u=u.slice(1));break}let p="normal",v=u.length-1;u[0]==="="&&(p="thick"),u[0]==="~"&&(p="invisible");let b=CUt(".",u);return b&&(p="dotted",v=b),{type:d,stroke:p,length:v}},aHe=(i,s)=>{const u=SUt(i);let d;if(s){if(d=TUt(s),d.stroke!==u.stroke)return{type:"INVALID",stroke:"INVALID"};if(d.type==="arrow_open")d.type=u.type;else{if(d.type!==u.type)return{type:"INVALID",stroke:"INVALID"};d.type="double_"+d.type}return d.type==="double_arrow"&&(d.type="double_arrow_point"),d.length=u.length,d}return u},oHe=(i,s)=>{let u=!1;return i.forEach(d=>{d.nodes.indexOf(s)>=0&&(u=!0)}),u},cHe=(i,s)=>{const u=[];return i.nodes.forEach((d,p)=>{oHe(s,d)||u.push(i.nodes[p])}),{nodes:u}},uHe={firstGraph:sHe},HC={defaultConfig:()=>Zje.flowchart,setAccTitle:Bg,getAccTitle:Cp,getAccDescription:_p,setAccDescription:Sp,addVertex:Nqe,lookUpDomId:mR,addLink:Bqe,updateLinkInterpolate:Fqe,updateLink:Rqe,addClass:jqe,setDirection:$qe,setClass:RQ,setTooltip:xUt,getTooltip:qqe,setClickEvent:Hqe,setLink:zqe,bindFunctions:Vqe,getDirection:Uqe,getVertices:Gqe,getEdges:Kqe,getClasses:Wqe,clear:Xqe,setGen:Qqe,defaultStyle:Jqe,addSubGraph:Zqe,getDepthFirstPos:nHe,indexNodes:rHe,getSubGraphs:iHe,destructLink:aHe,lex:uHe,exists:oHe,makeUniq:cHe,setDiagramTitle:cm,getDiagramTitle:Ap},_Ut=Object.freeze(Object.defineProperty({__proto__:null,addClass:jqe,addLink:Bqe,addSingleLink:Pqe,addSubGraph:Zqe,addVertex:Nqe,bindFunctions:Vqe,clear:Xqe,default:HC,defaultStyle:Jqe,destructLink:aHe,firstGraph:sHe,getClasses:Wqe,getDepthFirstPos:nHe,getDirection:Uqe,getEdges:Kqe,getSubGraphs:iHe,getTooltip:qqe,getVertices:Gqe,indexNodes:rHe,lex:uHe,lookUpDomId:mR,setClass:RQ,setClickEvent:Hqe,setDirection:$qe,setGen:Qqe,setLink:zqe,updateLink:Rqe,updateLinkInterpolate:Fqe},Symbol.toStringTag,{value:"Module"}));var AUt="[object Symbol]";function VC(i){return typeof i=="symbol"||q4(i)&&AC(i)==AUt}function RD(i,s){for(var u=-1,d=i==null?0:i.length,p=Array(d);++u-1}function fm(i){return w9(i)?aje(i):l$e(i)}var GUt=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,KUt=/^\w*$/;function Wbe(i,s){if(D0(i))return!1;var u=typeof i;return u=="number"||u=="symbol"||u=="boolean"||i==null||VC(i)?!0:KUt.test(i)||!GUt.test(i)||s!=null&&i in Object(s)}var WUt=500;function YUt(i){var s=bD(i,function(d){return u.size===WUt&&u.clear(),d}),u=s.cache;return s}var XUt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,QUt=/\\(\\)?/g,JUt=YUt(function(i){var s=[];return i.charCodeAt(0)===46&&s.push(""),i.replace(XUt,function(u,d,p,v){s.push(p?v.replace(QUt,"$1"):d||u)}),s});const ZUt=JUt;function mHe(i){return i==null?"":fHe(i)}function $Q(i,s){return D0(i)?i:Wbe(i,s)?[i]:ZUt(mHe(i))}var eGt=1/0;function wR(i){if(typeof i=="string"||VC(i))return i;var s=i+"";return s=="0"&&1/i==-eGt?"-0":s}function zQ(i,s){s=$Q(s,i);for(var u=0,d=s.length;i!=null&&u0&&u(y)?s>1?qQ(y,s-1,u,d,p):Ybe(p,y):d||(p[p.length]=y)}return p}function jD(i){var s=i==null?0:i.length;return s?qQ(i,1):[]}function rGt(i){return lje(uje(i,void 0,jD),i+"")}function iGt(i,s,u,d){var p=-1,v=i==null?0:i.length;for(d&&v&&(u=i[++p]);++py))return!1;var _=v.get(i),A=v.get(s);if(_&&A)return _==s&&A==i;var P=-1,R=!0,F=u&DKt?new xR:void 0;for(v.set(i,s),v.set(s,i);++P2?s[2]:void 0;for(p&&QF(s[0],s[1],p)&&(d=1);++u-1?p[v?s[b]:b]:void 0}}var yWt=Math.max;function xWt(i,s,u){var d=i==null?0:i.length;if(!d)return-1;var p=u==null?0:$Ut(u);return p<0&&(p=yWt(d+p,0)),bHe(i,I9(s),p)}var kWt=wWt(xWt);const rme=kWt;function VHe(i,s){var u=-1,d=w9(i)?Array(i.length):[];return VQ(i,function(p,v,b){d[++u]=s(p,v,b)}),d}function P0(i,s){var u=D0(i)?RD:VHe;return u(i,I9(s))}function EWt(i,s){return i==null?i:b2e(i,nme(s),IC)}function TWt(i,s){return i&&tme(i,nme(s))}function CWt(i,s){return i>s}var SWt=Object.prototype,_Wt=SWt.hasOwnProperty;function AWt(i,s){return i!=null&&_Wt.call(i,s)}function Lo(i,s){return i!=null&&$He(i,s,AWt)}function LWt(i,s){return RD(s,function(u){return i[u]})}function $7(i){return i==null?[]:LWt(i,fm(i))}function Qf(i){return i===void 0}function UHe(i,s){return is||v&&b&&T&&!y&&!_||d&&b&&T||!u&&T||!p)return 1;if(!d&&!v&&!_&&i=y)return T;var _=u[d];return T*(_=="desc"?-1:1)}}return i.index-s.index}function PWt(i,s,u){s.length?s=RD(s,function(v){return D0(v)?function(b){return zQ(b,v.length===1?v[0]:v)}:v}):s=[OC];var d=-1;s=RD(s,NX(I9));var p=VHe(i,function(v,b,y){var T=RD(s,function(_){return _(v)});return{criteria:T,index:++d,value:v}});return IWt(p,function(v,b){return NWt(v,b,u)})}function BWt(i,s){return DWt(i,s,function(u,d){return zHe(i,d)})}var FWt=rGt(function(i,s){return i==null?{}:BWt(i,s)});const ER=FWt;var RWt=Math.ceil,jWt=Math.max;function $Wt(i,s,u,d){for(var p=-1,v=jWt(RWt((s-i)/(u||1)),0),b=Array(v);v--;)b[d?v:++p]=i,i+=u;return b}function zWt(i){return function(s,u,d){return d&&typeof d!="number"&&QF(s,u,d)&&(u=d=void 0),s=jQ(s),u===void 0?(u=s,s=0):u=jQ(u),d=d===void 0?s1&&QF(i,s[0],s[1])?s=[]:u>2&&QF(s[0],s[1],s[2])&&(s=[s[0]]),PWt(i,qQ(s,1),[])});const CR=VWt;var UWt=1/0,GWt=CD&&1/Jbe(new CD([,-0]))[1]==UWt?function(i){return new CD(i)}:zUt;const KWt=GWt;var WWt=200;function YWt(i,s,u){var d=-1,p=UUt,v=i.length,b=!0,y=[],T=y;if(u)b=!1,p=mWt;else if(v>=WWt){var _=s?null:KWt(i);if(_)return Jbe(_);b=!1,p=IHe,T=new xR}else T=s?[]:y;e:for(;++d1?p.setNode(v,u):p.setNode(v)}),this}setNode(s,u){return Lo(this._nodes,s)?(arguments.length>1&&(this._nodes[s]=u),this):(this._nodes[s]=arguments.length>1?u:this._defaultNodeLabelFn(s),this._isCompound&&(this._parent[s]=KC,this._children[s]={},this._children[KC][s]=!0),this._in[s]={},this._preds[s]={},this._out[s]={},this._sucs[s]={},++this._nodeCount,this)}node(s){return this._nodes[s]}hasNode(s){return Lo(this._nodes,s)}removeNode(s){var u=this;if(Lo(this._nodes,s)){var d=function(p){u.removeEdge(u._edgeObjs[p])};delete this._nodes[s],this._isCompound&&(this._removeFromParentsChildList(s),delete this._parent[s],Ar(this.children(s),function(p){u.setParent(p)}),delete this._children[s]),Ar(fm(this._in[s]),d),delete this._in[s],delete this._preds[s],Ar(fm(this._out[s]),d),delete this._out[s],delete this._sucs[s],--this._nodeCount}return this}setParent(s,u){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(Qf(u))u=KC;else{u+="";for(var d=u;!Qf(d);d=this.parent(d))if(d===s)throw new Error("Setting "+u+" as parent of "+s+" would create a cycle");this.setNode(u)}return this.setNode(s),this._removeFromParentsChildList(s),this._parent[s]=u,this._children[u][s]=!0,this}_removeFromParentsChildList(s){delete this._children[this._parent[s]][s]}parent(s){if(this._isCompound){var u=this._parent[s];if(u!==KC)return u}}children(s){if(Qf(s)&&(s=KC),this._isCompound){var u=this._children[s];if(u)return fm(u)}else{if(s===KC)return this.nodes();if(this.hasNode(s))return[]}}predecessors(s){var u=this._preds[s];if(u)return fm(u)}successors(s){var u=this._sucs[s];if(u)return fm(u)}neighbors(s){var u=this.predecessors(s);if(u)return QWt(u,this.successors(s))}isLeaf(s){var u;return this.isDirected()?u=this.successors(s):u=this.neighbors(s),u.length===0}filterNodes(s){var u=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});u.setGraph(this.graph());var d=this;Ar(this._nodes,function(b,y){s(y)&&u.setNode(y,b)}),Ar(this._edgeObjs,function(b){u.hasNode(b.v)&&u.hasNode(b.w)&&u.setEdge(b,d.edge(b))});var p={};function v(b){var y=d.parent(b);return y===void 0||u.hasNode(y)?(p[b]=y,y):y in p?p[y]:v(y)}return this._isCompound&&Ar(u.nodes(),function(b){u.setParent(b,v(b))}),u}setDefaultEdgeLabel(s){return gD(s)||(s=yD(s)),this._defaultEdgeLabelFn=s,this}edgeCount(){return this._edgeCount}edges(){return $7(this._edgeObjs)}setPath(s,u){var d=this,p=arguments;return TR(s,function(v,b){return p.length>1?d.setEdge(v,b,u):d.setEdge(v,b),b}),this}setEdge(){var s,u,d,p,v=!1,b=arguments[0];typeof b=="object"&&b!==null&&"v"in b?(s=b.v,u=b.w,d=b.name,arguments.length===2&&(p=arguments[1],v=!0)):(s=b,u=arguments[1],d=arguments[3],arguments.length>2&&(p=arguments[2],v=!0)),s=""+s,u=""+u,Qf(d)||(d=""+d);var y=SR(this._isDirected,s,u,d);if(Lo(this._edgeLabels,y))return v&&(this._edgeLabels[y]=p),this;if(!Qf(d)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(s),this.setNode(u),this._edgeLabels[y]=v?p:this._defaultEdgeLabelFn(s,u,d);var T=nYt(this._isDirected,s,u,d);return s=T.v,u=T.w,Object.freeze(T),this._edgeObjs[y]=T,KHe(this._preds[u],s),KHe(this._sucs[s],u),this._in[u][y]=T,this._out[s][y]=T,this._edgeCount++,this}edge(s,u,d){var p=arguments.length===1?ame(this._isDirected,arguments[0]):SR(this._isDirected,s,u,d);return this._edgeLabels[p]}hasEdge(s,u,d){var p=arguments.length===1?ame(this._isDirected,arguments[0]):SR(this._isDirected,s,u,d);return Lo(this._edgeLabels,p)}removeEdge(s,u,d){var p=arguments.length===1?ame(this._isDirected,arguments[0]):SR(this._isDirected,s,u,d),v=this._edgeObjs[p];return v&&(s=v.v,u=v.w,delete this._edgeLabels[p],delete this._edgeObjs[p],WHe(this._preds[u],s),WHe(this._sucs[s],u),delete this._in[u][p],delete this._out[s][p],this._edgeCount--),this}inEdges(s,u){var d=this._in[s];if(d){var p=$7(d);return u?j7(p,function(v){return v.v===u}):p}}outEdges(s,u){var d=this._out[s];if(d){var p=$7(d);return u?j7(p,function(v){return v.w===u}):p}}nodeEdges(s,u){var d=this.inEdges(s,u);if(d)return d.concat(this.outEdges(s,u))}}B0.prototype._nodeCount=0,B0.prototype._edgeCount=0;function KHe(i,s){i[s]?i[s]++:i[s]=1}function WHe(i,s){--i[s]||delete i[s]}function SR(i,s,u,d){var p=""+s,v=""+u;if(!i&&p>v){var b=p;p=v,v=b}return p+GHe+v+GHe+(Qf(d)?tYt:d)}function nYt(i,s,u,d){var p=""+s,v=""+u;if(!i&&p>v){var b=p;p=v,v=b}var y={v:p,w:v};return d&&(y.name=d),y}function ame(i,s){return SR(i,s.v,s.w,s.name)}class rYt{constructor(){var s={};s._next=s._prev=s,this._sentinel=s}dequeue(){var s=this._sentinel,u=s._prev;if(u!==s)return YHe(u),u}enqueue(s){var u=this._sentinel;s._prev&&s._next&&YHe(s),s._next=u._next,u._next._prev=s,u._next=s,s._prev=u}toString(){for(var s=[],u=this._sentinel,d=u._prev;d!==u;)s.push(JSON.stringify(d,iYt)),d=d._prev;return"["+s.join(", ")+"]"}}function YHe(i){i._prev._next=i._next,i._next._prev=i._prev,delete i._next,delete i._prev}function iYt(i,s){if(i!=="_next"&&i!=="_prev")return s}var sYt=yD(1);function aYt(i,s){if(i.nodeCount()<=1)return[];var u=cYt(i,s||sYt),d=oYt(u.graph,u.buckets,u.zeroIdx);return jD(P0(d,function(p){return i.outEdges(p.v,p.w)}))}function oYt(i,s,u){for(var d=[],p=s[s.length-1],v=s[0],b;i.nodeCount();){for(;b=v.dequeue();)ome(i,s,u,b);for(;b=p.dequeue();)ome(i,s,u,b);if(i.nodeCount()){for(var y=s.length-2;y>0;--y)if(b=s[y].dequeue(),b){d=d.concat(ome(i,s,u,b,!0));break}}}return d}function ome(i,s,u,d,p){var v=p?[]:void 0;return Ar(i.inEdges(d.v),function(b){var y=i.edge(b),T=i.node(b.v);p&&v.push({v:b.v,w:b.w}),T.out-=y,cme(s,u,T)}),Ar(i.outEdges(d.v),function(b){var y=i.edge(b),T=b.w,_=i.node(T);_.in-=y,cme(s,u,_)}),i.removeNode(d.v),v}function cYt(i,s){var u=new B0,d=0,p=0;Ar(i.nodes(),function(y){u.setNode(y,{v:y,in:0,out:0})}),Ar(i.edges(),function(y){var T=u.edge(y.v,y.w)||0,_=s(y),A=T+_;u.setEdge(y.v,y.w,A),p=Math.max(p,u.node(y.v).out+=_),d=Math.max(d,u.node(y.w).in+=_)});var v=GC(p+d+3).map(function(){return new rYt}),b=d+1;return Ar(u.nodes(),function(y){cme(v,b,u.node(y))}),{graph:u,buckets:v,zeroIdx:b}}function cme(i,s,u){u.out?u.in?i[u.out-u.in+s].enqueue(u):i[i.length-1].enqueue(u):i[0].enqueue(u)}function uYt(i){var s=i.graph().acyclicer==="greedy"?aYt(i,u(i)):lYt(i);Ar(s,function(d){var p=i.edge(d);i.removeEdge(d),p.forwardName=d.name,p.reversed=!0,i.setEdge(d.w,d.v,p,KQ("rev"))});function u(d){return function(p){return d.edge(p).weight}}}function lYt(i){var s=[],u={},d={};function p(v){Lo(d,v)||(d[v]=!0,u[v]=!0,Ar(i.outEdges(v),function(b){Lo(u,b.w)?s.push(b):p(b.w)}),delete u[v])}return Ar(i.nodes(),p),s}function hYt(i){Ar(i.edges(),function(s){var u=i.edge(s);if(u.reversed){i.removeEdge(s);var d=u.forwardName;delete u.reversed,delete u.forwardName,i.setEdge(s.w,s.v,u,d)}})}function zD(i,s,u,d){var p;do p=KQ(d);while(i.hasNode(p));return u.dummy=s,i.setNode(p,u),p}function fYt(i){var s=new B0().setGraph(i.graph());return Ar(i.nodes(),function(u){s.setNode(u,i.node(u))}),Ar(i.edges(),function(u){var d=s.edge(u.v,u.w)||{weight:0,minlen:1},p=i.edge(u);s.setEdge(u.v,u.w,{weight:d.weight+p.weight,minlen:Math.max(d.minlen,p.minlen)})}),s}function XHe(i){var s=new B0({multigraph:i.isMultigraph()}).setGraph(i.graph());return Ar(i.nodes(),function(u){i.children(u).length||s.setNode(u,i.node(u))}),Ar(i.edges(),function(u){s.setEdge(u,i.edge(u))}),s}function QHe(i,s){var u=i.x,d=i.y,p=s.x-u,v=s.y-d,b=i.width/2,y=i.height/2;if(!p&&!v)throw new Error("Not possible to find intersection inside of the rectangle");var T,_;return Math.abs(v)*b>Math.abs(p)*y?(v<0&&(y=-y),T=y*p/v,_=y):(p<0&&(b=-b),T=b,_=b*v/p),{x:u+T,y:d+_}}function WQ(i){var s=P0(GC(ZHe(i)+1),function(){return[]});return Ar(i.nodes(),function(u){var d=i.node(u),p=d.rank;Qf(p)||(s[p][d.order]=u)}),s}function dYt(i){var s=kR(P0(i.nodes(),function(u){return i.node(u).rank}));Ar(i.nodes(),function(u){var d=i.node(u);Lo(d,"rank")&&(d.rank-=s)})}function gYt(i){var s=kR(P0(i.nodes(),function(v){return i.node(v).rank})),u=[];Ar(i.nodes(),function(v){var b=i.node(v).rank-s;u[b]||(u[b]=[]),u[b].push(v)});var d=0,p=i.graph().nodeRankFactor;Ar(u,function(v,b){Qf(v)&&b%p!==0?--d:d&&Ar(v,function(y){i.node(y).rank+=d})})}function JHe(i,s,u,d){var p={width:0,height:0};return arguments.length>=4&&(p.rank=u,p.order=d),zD(i,"border",p,s)}function ZHe(i){return UC(P0(i.nodes(),function(s){var u=i.node(s).rank;if(!Qf(u))return u}))}function pYt(i,s){var u={lhs:[],rhs:[]};return Ar(i,function(d){s(d)?u.lhs.push(d):u.rhs.push(d)}),u}function bYt(i,s){var u=qHe();try{return s()}finally{console.log(i+" time: "+(qHe()-u)+"ms")}}function mYt(i,s){return s()}function vYt(i){function s(u){var d=i.children(u),p=i.node(u);if(d.length&&Ar(d,s),Lo(p,"minRank")){p.borderLeft=[],p.borderRight=[];for(var v=p.minRank,b=p.maxRank+1;vb.lim&&(y=b,T=!0);var _=j7(s.edges(),function(A){return T===hVe(i,i.node(A.v),y)&&T!==hVe(i,i.node(A.w),y)});return sme(_,function(A){return _R(s,A)})}function lVe(i,s,u,d){var p=u.v,v=u.w;i.removeEdge(p,v),i.setEdge(d.v,d.w,{}),dme(i),fme(i,s),OYt(i,s)}function OYt(i,s){var u=rme(i.nodes(),function(p){return!s.node(p).parent}),d=DYt(i,u);d=d.slice(1),Ar(d,function(p){var v=i.node(p).parent,b=s.edge(p,v),y=!1;b||(b=s.edge(v,p),y=!0),s.node(p).rank=s.node(v).rank+(y?b.minlen:-b.minlen)})}function NYt(i,s,u){return i.hasEdge(s,u)}function hVe(i,s,u){return u.low<=s.lim&&s.lim<=u.lim}function PYt(i){switch(i.graph().ranker){case"network-simplex":fVe(i);break;case"tight-tree":FYt(i);break;case"longest-path":BYt(i);break;default:fVe(i)}}var BYt=hme;function FYt(i){hme(i),rVe(i)}function fVe(i){WC(i)}function RYt(i){var s=zD(i,"root",{},"_root"),u=jYt(i),d=UC($7(u))-1,p=2*d+1;i.graph().nestingRoot=s,Ar(i.edges(),function(b){i.edge(b).minlen*=p});var v=$Yt(i)+1;Ar(i.children(),function(b){dVe(i,s,p,v,d,u,b)}),i.graph().nodeRankFactor=p}function dVe(i,s,u,d,p,v,b){var y=i.children(b);if(!y.length){b!==s&&i.setEdge(s,b,{weight:0,minlen:u});return}var T=JHe(i,"_bt"),_=JHe(i,"_bb"),A=i.node(b);i.setParent(T,b),A.borderTop=T,i.setParent(_,b),A.borderBottom=_,Ar(y,function(P){dVe(i,s,u,d,p,v,P);var R=i.node(P),F=R.borderTop?R.borderTop:P,j=R.borderBottom?R.borderBottom:P,K=R.borderTop?d:2*d,ee=F!==j?1:p-v[b]+1;i.setEdge(T,F,{weight:K,minlen:ee,nestingEdge:!0}),i.setEdge(j,_,{weight:K,minlen:ee,nestingEdge:!0})}),i.parent(b)||i.setEdge(s,T,{weight:0,minlen:p+v[b]})}function jYt(i){var s={};function u(d,p){var v=i.children(d);v&&v.length&&Ar(v,function(b){u(b,p+1)}),s[d]=p}return Ar(i.children(),function(d){u(d,1)}),s}function $Yt(i){return TR(i.edges(),function(s,u){return s+i.edge(u).weight},0)}function zYt(i){var s=i.graph();i.removeNode(s.nestingRoot),delete s.nestingRoot,Ar(i.edges(),function(u){var d=i.edge(u);d.nestingEdge&&i.removeEdge(u)})}function qYt(i,s,u){var d={},p;Ar(u,function(v){for(var b=i.parent(v),y,T;b;){if(y=i.parent(b),y?(T=d[y],d[y]=b):(T=p,p=b),T&&T!==b){s.setEdge(T,b);return}b=y}})}function HYt(i,s,u){var d=VYt(i),p=new B0({compound:!0}).setGraph({root:d}).setDefaultNodeLabel(function(v){return i.node(v)});return Ar(i.nodes(),function(v){var b=i.node(v),y=i.parent(v);(b.rank===s||b.minRank<=s&&s<=b.maxRank)&&(p.setNode(v),p.setParent(v,y||d),Ar(i[u](v),function(T){var _=T.v===v?T.w:T.v,A=p.edge(_,v),P=Qf(A)?0:A.weight;p.setEdge(_,v,{weight:i.edge(T).weight+P})}),Lo(b,"minRank")&&p.setNode(v,{borderLeft:b.borderLeft[s],borderRight:b.borderRight[s]}))}),p}function VYt(i){for(var s;i.hasNode(s=KQ("_root")););return s}function UYt(i,s){for(var u=0,d=1;d0;)A%2&&(P+=y[A+1]),A=A-1>>1,y[A]+=_.weight;T+=_.weight*P})),T}function KYt(i){var s={},u=j7(i.nodes(),function(y){return!i.children(y).length}),d=UC(P0(u,function(y){return i.node(y).rank})),p=P0(GC(d+1),function(){return[]});function v(y){if(!Lo(s,y)){s[y]=!0;var T=i.node(y);p[T.rank].push(y),Ar(i.successors(y),v)}}var b=CR(u,function(y){return i.node(y).rank});return Ar(b,v),p}function WYt(i,s){return P0(s,function(u){var d=i.inEdges(u);if(d.length){var p=TR(d,function(v,b){var y=i.edge(b),T=i.node(b.v);return{sum:v.sum+y.weight*T.order,weight:v.weight+y.weight}},{sum:0,weight:0});return{v:u,barycenter:p.sum/p.weight,weight:p.weight}}else return{v:u}})}function YYt(i,s){var u={};Ar(i,function(p,v){var b=u[p.v]={indegree:0,in:[],out:[],vs:[p.v],i:v};Qf(p.barycenter)||(b.barycenter=p.barycenter,b.weight=p.weight)}),Ar(s.edges(),function(p){var v=u[p.v],b=u[p.w];!Qf(v)&&!Qf(b)&&(b.indegree++,v.out.push(u[p.w]))});var d=j7(u,function(p){return!p.indegree});return XYt(d)}function XYt(i){var s=[];function u(v){return function(b){b.merged||(Qf(b.barycenter)||Qf(v.barycenter)||b.barycenter>=v.barycenter)&&QYt(v,b)}}function d(v){return function(b){b.in.push(v),--b.indegree===0&&i.push(b)}}for(;i.length;){var p=i.pop();s.push(p),Ar(p.in.reverse(),u(p)),Ar(p.out,d(p))}return P0(j7(s,function(v){return!v.merged}),function(v){return ER(v,["vs","i","barycenter","weight"])})}function QYt(i,s){var u=0,d=0;i.weight&&(u+=i.barycenter*i.weight,d+=i.weight),s.weight&&(u+=s.barycenter*s.weight,d+=s.weight),i.vs=s.vs.concat(i.vs),i.barycenter=u/d,i.weight=d,i.i=Math.min(s.i,i.i),s.merged=!0}function JYt(i,s){var u=pYt(i,function(A){return Lo(A,"barycenter")}),d=u.lhs,p=CR(u.rhs,function(A){return-A.i}),v=[],b=0,y=0,T=0;d.sort(ZYt(!!s)),T=gVe(v,p,T),Ar(d,function(A){T+=A.vs.length,v.push(A.vs),b+=A.barycenter*A.weight,y+=A.weight,T=gVe(v,p,T)});var _={vs:jD(v)};return y&&(_.barycenter=b/y,_.weight=y),_}function gVe(i,s,u){for(var d;s.length&&(d=UQ(s)).i<=u;)s.pop(),i.push(d.vs),u++;return u}function ZYt(i){return function(s,u){return s.barycenteru.barycenter?1:i?u.i-s.i:s.i-u.i}}function pVe(i,s,u,d){var p=i.children(s),v=i.node(s),b=v?v.borderLeft:void 0,y=v?v.borderRight:void 0,T={};b&&(p=j7(p,function(j){return j!==b&&j!==y}));var _=WYt(i,p);Ar(_,function(j){if(i.children(j.v).length){var K=pVe(i,j.v,u,d);T[j.v]=K,Lo(K,"barycenter")&&tXt(j,K)}});var A=YYt(_,u);eXt(A,T);var P=JYt(A,d);if(b&&(P.vs=jD([b,P.vs,y]),i.predecessors(b).length)){var R=i.node(i.predecessors(b)[0]),F=i.node(i.predecessors(y)[0]);Lo(P,"barycenter")||(P.barycenter=0,P.weight=0),P.barycenter=(P.barycenter*P.weight+R.order+F.order)/(P.weight+2),P.weight+=2}return P}function eXt(i,s){Ar(i,function(u){u.vs=jD(u.vs.map(function(d){return s[d]?s[d].vs:d}))})}function tXt(i,s){Qf(i.barycenter)?(i.barycenter=s.barycenter,i.weight=s.weight):(i.barycenter=(i.barycenter*i.weight+s.barycenter*s.weight)/(i.weight+s.weight),i.weight+=s.weight)}function nXt(i){var s=ZHe(i),u=bVe(i,GC(1,s+1),"inEdges"),d=bVe(i,GC(s-1,-1,-1),"outEdges"),p=KYt(i);mVe(i,p);for(var v=Number.POSITIVE_INFINITY,b,y=0,T=0;T<4;++y,++T){rXt(y%2?u:d,y%4>=2),p=WQ(i);var _=UYt(i,p);_b||y>s[T].lim));for(_=T,T=d;(T=i.parent(T))!==_;)v.push(T);return{path:p.concat(v.reverse()),lca:_}}function aXt(i){var s={},u=0;function d(p){var v=u;Ar(i.children(p),d),s[p]={low:v,lim:u++}}return Ar(i.children(),d),s}function oXt(i,s){var u={};function d(p,v){var b=0,y=0,T=p.length,_=UQ(v);return Ar(v,function(A,P){var R=uXt(i,A),F=R?i.node(R).order:T;(R||A===_)&&(Ar(v.slice(y,P+1),function(j){Ar(i.predecessors(j),function(K){var ee=i.node(K),ie=ee.order;(ie_)&&vVe(u,R,A)})})}function p(v,b){var y=-1,T,_=0;return Ar(b,function(A,P){if(i.node(A).dummy==="border"){var R=i.predecessors(A);R.length&&(T=i.node(R[0]).order,d(b,_,P,y,T),_=P,y=T)}d(b,_,b.length,T,v.length)}),b}return TR(s,p),u}function uXt(i,s){if(i.node(s).dummy)return rme(i.predecessors(s),function(u){return i.node(u).dummy})}function vVe(i,s,u){if(s>u){var d=s;s=u,u=d}var p=i[s];p||(i[s]=p={}),p[u]=!0}function lXt(i,s,u){if(s>u){var d=s;s=u,u=d}return Lo(i[s],u)}function hXt(i,s,u,d){var p={},v={},b={};return Ar(s,function(y){Ar(y,function(T,_){p[T]=T,v[T]=T,b[T]=_})}),Ar(s,function(y){var T=-1;Ar(y,function(_){var A=d(_);if(A.length){A=CR(A,function(K){return b[K]});for(var P=(A.length-1)/2,R=Math.floor(P),F=Math.ceil(P);R<=F;++R){var j=A[R];v[_]===_&&T0}function e5(i,s,u){var d=i.x,p=i.y,v=[],b=Number.POSITIVE_INFINITY,y=Number.POSITIVE_INFINITY;s.forEach(function(j){b=Math.min(b,j.x),y=Math.min(y,j.y)});for(var T=d-i.width/2-b,_=p-i.height/2-y,A=0;A1&&v.sort(function(j,K){var ee=j.x-u.x,ie=j.y-u.y,oe=Math.sqrt(ee*ee+ie*ie),pe=K.x-u.x,be=K.y-u.y,ae=Math.sqrt(pe*pe+be*be);return oeMath.abs(p)*y?(v<0&&(y=-y),T=v===0?0:y*p/v,_=y):(p<0&&(b=-b),T=b,_=p===0?0:b*v/p),{x:u+T,y:d+_}}var Cme={rect:gQt,ellipse:pQt,circle:bQt,diamond:mQt};function dQt(i){Cme=i}function gQt(i,s,u){var d=i.insert("rect",":first-child").attr("rx",u.rx).attr("ry",u.ry).attr("x",-s.width/2).attr("y",-s.height/2).attr("width",s.width).attr("height",s.height);return u.intersect=function(p){return Tme(u,p)},d}function pQt(i,s,u){var d=s.width/2,p=s.height/2,v=i.insert("ellipse",":first-child").attr("x",-s.width/2).attr("y",-s.height/2).attr("rx",d).attr("ry",p);return u.intersect=function(b){return TVe(u,d,p,b)},v}function bQt(i,s,u){var d=Math.max(s.width,s.height)/2,p=i.insert("circle",":first-child").attr("x",-s.width/2).attr("y",-s.height/2).attr("r",d);return u.intersect=function(v){return hQt(u,d,v)},p}function mQt(i,s,u){var d=s.width*Math.SQRT2/2,p=s.height*Math.SQRT2/2,v=[{x:0,y:-p},{x:-d,y:0},{x:0,y:p},{x:d,y:0}],b=i.insert("polygon",":first-child").attr("points",v.map(function(y){return y.x+","+y.y}).join(" "));return u.intersect=function(y){return e5(u,v,y)},b}function vQt(){var i=function(s,u){xQt(u);var d=AR(s,"output"),p=AR(d,"clusters"),v=AR(d,"edgePaths"),b=xme(AR(d,"edgeLabels"),u),y=Eme(AR(d,"nodes"),u,Cme);qD(u),lQt(y,u),uQt(b,u),kme(v,u,mme);var T=yme(p,u);cQt(T,u),kQt(u)};return i.createNodes=function(s){return arguments.length?(oQt(s),i):Eme},i.createClusters=function(s){return arguments.length?(ZXt(s),i):yme},i.createEdgeLabels=function(s){return arguments.length?(eQt(s),i):xme},i.createEdgePaths=function(s){return arguments.length?(tQt(s),i):kme},i.shapes=function(s){return arguments.length?(dQt(s),i):Cme},i.arrows=function(s){return arguments.length?(GXt(s),i):mme},i}var wQt={paddingLeft:10,paddingRight:10,paddingTop:10,paddingBottom:10,rx:0,ry:0,shape:"rect"},yQt={arrowhead:"normal",curve:kp};function xQt(i){i.nodes().forEach(function(s){var u=i.node(s);!Lo(u,"label")&&!i.children(s).length&&(u.label=s),Lo(u,"paddingX")&&$D(u,{paddingLeft:u.paddingX,paddingRight:u.paddingX}),Lo(u,"paddingY")&&$D(u,{paddingTop:u.paddingY,paddingBottom:u.paddingY}),Lo(u,"padding")&&$D(u,{paddingLeft:u.padding,paddingRight:u.padding,paddingTop:u.padding,paddingBottom:u.padding}),$D(u,wQt),Ar(["paddingLeft","paddingRight","paddingTop","paddingBottom"],function(d){u[d]=Number(u[d])}),Lo(u,"width")&&(u._prevWidth=u.width),Lo(u,"height")&&(u._prevHeight=u.height)}),i.edges().forEach(function(s){var u=i.edge(s);Lo(u,"label")||(u.label=""),$D(u,yQt)})}function kQt(i){Ar(i.nodes(),function(s){var u=i.node(s);Lo(u,"_prevWidth")?u.width=u._prevWidth:delete u.width,Lo(u,"_prevHeight")?u.height=u._prevHeight:delete u.height,delete u._prevWidth,delete u._prevHeight})}function AR(i,s){var u=i.select("g."+s);return u.empty()&&(u=i.append("g").attr("class",s)),u}function SVe(i,s,u){const d=s.width,p=s.height,v=(d+p)*.9,b=[{x:v/2,y:0},{x:v,y:-v/2},{x:v/2,y:-v},{x:0,y:-v/2}],y=z7(i,v,v,b);return u.intersect=function(T){return e5(u,b,T)},y}function _Ve(i,s,u){const p=s.height,v=p/4,b=s.width+2*v,y=[{x:v,y:0},{x:b-v,y:0},{x:b,y:-p/2},{x:b-v,y:-p},{x:v,y:-p},{x:0,y:-p/2}],T=z7(i,b,p,y);return u.intersect=function(_){return e5(u,y,_)},T}function AVe(i,s,u){const d=s.width,p=s.height,v=[{x:-p/2,y:0},{x:d,y:0},{x:d,y:-p},{x:-p/2,y:-p},{x:0,y:-p/2}],b=z7(i,d,p,v);return u.intersect=function(y){return e5(u,v,y)},b}function LVe(i,s,u){const d=s.width,p=s.height,v=[{x:-2*p/6,y:0},{x:d-p/6,y:0},{x:d+2*p/6,y:-p},{x:p/6,y:-p}],b=z7(i,d,p,v);return u.intersect=function(y){return e5(u,v,y)},b}function MVe(i,s,u){const d=s.width,p=s.height,v=[{x:2*p/6,y:0},{x:d+p/6,y:0},{x:d-2*p/6,y:-p},{x:-p/6,y:-p}],b=z7(i,d,p,v);return u.intersect=function(y){return e5(u,v,y)},b}function DVe(i,s,u){const d=s.width,p=s.height,v=[{x:-2*p/6,y:0},{x:d+2*p/6,y:0},{x:d-p/6,y:-p},{x:p/6,y:-p}],b=z7(i,d,p,v);return u.intersect=function(y){return e5(u,v,y)},b}function IVe(i,s,u){const d=s.width,p=s.height,v=[{x:p/6,y:0},{x:d-p/6,y:0},{x:d+2*p/6,y:-p},{x:-2*p/6,y:-p}],b=z7(i,d,p,v);return u.intersect=function(y){return e5(u,v,y)},b}function OVe(i,s,u){const d=s.width,p=s.height,v=[{x:0,y:0},{x:d+p/2,y:0},{x:d,y:-p/2},{x:d+p/2,y:-p},{x:0,y:-p}],b=z7(i,d,p,v);return u.intersect=function(y){return e5(u,v,y)},b}function NVe(i,s,u){const d=s.height,p=s.width+d/4,v=i.insert("rect",":first-child").attr("rx",d/2).attr("ry",d/2).attr("x",-p/2).attr("y",-d/2).attr("width",p).attr("height",d);return u.intersect=function(b){return Tme(u,b)},v}function PVe(i,s,u){const d=s.width,p=s.height,v=[{x:0,y:0},{x:d,y:0},{x:d,y:-p},{x:0,y:-p},{x:0,y:0},{x:-8,y:0},{x:d+8,y:0},{x:d+8,y:-p},{x:-8,y:-p},{x:-8,y:0}],b=z7(i,d,p,v);return u.intersect=function(y){return e5(u,v,y)},b}function BVe(i,s,u){const d=s.width,p=d/2,v=p/(2.5+d/50),b=s.height+v,y="M 0,"+v+" a "+p+","+v+" 0,0,0 "+d+" 0 a "+p+","+v+" 0,0,0 "+-d+" 0 l 0,"+b+" a "+p+","+v+" 0,0,0 "+d+" 0 l 0,"+-b,T=i.attr("label-offset-y",v).insert("path",":first-child").attr("d",y).attr("transform","translate("+-d/2+","+-(b/2+v)+")");return u.intersect=function(_){const A=Tme(u,_),P=A.x-u.x;if(p!=0&&(Math.abs(P)u.height/2-v)){let R=v*v*(1-P*P/(p*p));R!=0&&(R=Math.sqrt(R)),R=v-R,_.y-u.y>0&&(R=-R),A.y+=R}return A},T}function EQt(i){i.shapes().question=SVe,i.shapes().hexagon=_Ve,i.shapes().stadium=NVe,i.shapes().subroutine=PVe,i.shapes().cylinder=BVe,i.shapes().rect_left_inv_arrow=AVe,i.shapes().lean_right=LVe,i.shapes().lean_left=MVe,i.shapes().trapezoid=DVe,i.shapes().inv_trapezoid=IVe,i.shapes().rect_right_inv_arrow=OVe}function TQt(i){i({question:SVe}),i({hexagon:_Ve}),i({stadium:NVe}),i({subroutine:PVe}),i({cylinder:BVe}),i({rect_left_inv_arrow:AVe}),i({lean_right:LVe}),i({lean_left:MVe}),i({trapezoid:DVe}),i({inv_trapezoid:IVe}),i({rect_right_inv_arrow:OVe})}function z7(i,s,u,d){return i.insert("polygon",":first-child").attr("points",d.map(function(p){return p.x+","+p.y}).join(" ")).attr("transform","translate("+-s/2+","+u/2+")")}const CQt={addToRender:EQt,addToRenderV2:TQt},FVe={},SQt=function(i){const s=Object.keys(i);for(const u of s)FVe[u]=i[u]},RVe=async function(i,s,u,d,p,v){const b=d?d.select(`[id="${u}"]`):Ir(`[id="${u}"]`),y=p||document,T=Object.keys(i);for(const _ of T){const A=i[_];let P="default";A.classes.length>0&&(P=A.classes.join(" "));const R=om(A.styles);let F=A.text!==void 0?A.text:A.id,j;if(f1(qt().flowchart.htmlLabels)){const ie={label:await CC(F.replace(/fa[blrs]?:fa-[\w-]+/g,oe=>``),qt())};j=vme(b,ie).node(),j.parentNode.removeChild(j)}else{const ie=y.createElementNS("http://www.w3.org/2000/svg","text");ie.setAttribute("style",R.labelStyle.replace("color:","fill:"));const oe=F.split(ci.lineBreakRegex);for(const pe of oe){const be=y.createElementNS("http://www.w3.org/2000/svg","tspan");be.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),be.setAttribute("dy","1em"),be.setAttribute("x","1"),be.textContent=pe,ie.appendChild(be)}j=ie}let K=0,ee="";switch(A.type){case"round":K=5,ee="rect";break;case"square":ee="rect";break;case"diamond":ee="question";break;case"hexagon":ee="hexagon";break;case"odd":ee="rect_left_inv_arrow";break;case"lean_right":ee="lean_right";break;case"lean_left":ee="lean_left";break;case"trapezoid":ee="trapezoid";break;case"inv_trapezoid":ee="inv_trapezoid";break;case"odd_right":ee="rect_left_inv_arrow";break;case"circle":ee="circle";break;case"ellipse":ee="ellipse";break;case"stadium":ee="stadium";break;case"subroutine":ee="subroutine";break;case"cylinder":ee="cylinder";break;case"group":ee="rect";break;default:ee="rect"}Xe.warn("Adding node",A.id,A.domId),s.setNode(v.db.lookUpDomId(A.id),{labelType:"svg",labelStyle:R.labelStyle,shape:ee,label:j,rx:K,ry:K,class:P,style:R.style,id:v.db.lookUpDomId(A.id)})}},jVe=async function(i,s,u){let d=0,p,v;if(i.defaultStyle!==void 0){const b=om(i.defaultStyle);p=b.style,v=b.labelStyle}for(const b of i){d++;const y="L-"+b.start+"-"+b.end,T="LS-"+b.start,_="LE-"+b.end,A={};b.type==="arrow_open"?A.arrowhead="none":A.arrowhead="normal";let P="",R="";if(b.style!==void 0){const F=om(b.style);P=F.style,R=F.labelStyle}else switch(b.stroke){case"normal":P="fill:none",p!==void 0&&(P=p),v!==void 0&&(R=v);break;case"dotted":P="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":P=" stroke-width: 3.5px;fill:none";break}A.style=P,A.labelStyle=R,b.interpolate!==void 0?A.curve=Ov(b.interpolate,kp):i.defaultInterpolate!==void 0?A.curve=Ov(i.defaultInterpolate,kp):A.curve=Ov(FVe.curve,kp),b.text===void 0?b.style!==void 0&&(A.arrowheadStyle="fill: #333"):(A.arrowheadStyle="fill: #333",A.labelpos="c",f1(qt().flowchart.htmlLabels)?(A.labelType="html",A.label=`${await CC(b.text.replace(/fa[blrs]?:fa-[\w-]+/g,F=>``),qt())}`):(A.labelType="text",A.label=b.text.replace(ci.lineBreakRegex,` +`),b.style===void 0&&(A.style=A.style||"stroke: #333; stroke-width: 1.5px;fill:none"),A.labelStyle=A.labelStyle.replace("color:","fill:"))),A.id=y,A.class=T+" "+_,A.minlen=b.length||1,s.setEdge(u.db.lookUpDomId(b.start),u.db.lookUpDomId(b.end),A,d)}},_Qt={setConf:SQt,addVertices:RVe,addEdges:jVe,getClasses:function(i,s){return Xe.info("Extracting classes"),s.db.getClasses()},draw:async function(i,s,u,d){Xe.info("Drawing flowchart");const{securityLevel:p,flowchart:v}=qt();let b;p==="sandbox"&&(b=Ir("#i"+s));const y=Ir(p==="sandbox"?b.nodes()[0].contentDocument.body:"body"),T=p==="sandbox"?b.nodes()[0].contentDocument:document;let _=d.db.getDirection();_===void 0&&(_="TD");const A=v.nodeSpacing||50,P=v.rankSpacing||50,R=new B0({multigraph:!0,compound:!0}).setGraph({rankdir:_,nodesep:A,ranksep:P,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});let F;const j=d.db.getSubGraphs();for(let ne=j.length-1;ne>=0;ne--)F=j[ne],d.db.addVertex(F.id,F.title,"group",void 0,F.classes);const K=d.db.getVertices();Xe.warn("Get vertices",K);const ee=d.db.getEdges();let ie=0;for(ie=j.length-1;ie>=0;ie--){F=j[ie],_Be("cluster").append("text");for(let ne=0;ne{s.forEach(p=>{DQt[p](i,u,d)})},DQt={extension:(i,s,u)=>{Xe.trace("Making markers for ",u),i.append("defs").append("marker").attr("id",u+"_"+s+"-extensionStart").attr("class","marker extension "+s).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"),i.append("defs").append("marker").attr("id",u+"_"+s+"-extensionEnd").attr("class","marker extension "+s).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")},composition:(i,s,u)=>{i.append("defs").append("marker").attr("id",u+"_"+s+"-compositionStart").attr("class","marker composition "+s).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"),i.append("defs").append("marker").attr("id",u+"_"+s+"-compositionEnd").attr("class","marker composition "+s).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:(i,s,u)=>{i.append("defs").append("marker").attr("id",u+"_"+s+"-aggregationStart").attr("class","marker aggregation "+s).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"),i.append("defs").append("marker").attr("id",u+"_"+s+"-aggregationEnd").attr("class","marker aggregation "+s).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")},dependency:(i,s,u)=>{i.append("defs").append("marker").attr("id",u+"_"+s+"-dependencyStart").attr("class","marker dependency "+s).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"),i.append("defs").append("marker").attr("id",u+"_"+s+"-dependencyEnd").attr("class","marker dependency "+s).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")},lollipop:(i,s,u)=>{i.append("defs").append("marker").attr("id",u+"_"+s+"-lollipopStart").attr("class","marker lollipop "+s).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),i.append("defs").append("marker").attr("id",u+"_"+s+"-lollipopEnd").attr("class","marker lollipop "+s).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)},point:(i,s,u)=>{i.append("marker").attr("id",u+"_"+s+"-pointEnd").attr("class","marker "+s).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"),i.append("marker").attr("id",u+"_"+s+"-pointStart").attr("class","marker "+s).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")},circle:(i,s,u)=>{i.append("marker").attr("id",u+"_"+s+"-circleEnd").attr("class","marker "+s).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"),i.append("marker").attr("id",u+"_"+s+"-circleStart").attr("class","marker "+s).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")},cross:(i,s,u)=>{i.append("marker").attr("id",u+"_"+s+"-crossEnd").attr("class","marker cross "+s).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"),i.append("marker").attr("id",u+"_"+s+"-crossStart").attr("class","marker cross "+s).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")},barb:(i,s,u)=>{i.append("defs").append("marker").attr("id",u+"_"+s+"-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")}},Sme=MQt;function IQt(i,s){s&&i.attr("style",s)}function OQt(i){const s=Ir(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),u=s.append("xhtml:div"),d=i.label,p=i.isNode?"nodeLabel":"edgeLabel";return u.html('"+d+""),IQt(u,i.labelStyle),u.style("display","inline-block"),u.style("white-space","nowrap"),u.attr("xmlns","http://www.w3.org/1999/xhtml"),s.node()}const $2=(i,s,u,d)=>{let p=i||"";if(typeof p=="object"&&(p=p[0]),f1(qt().flowchart.htmlLabels)){p=p.replace(/\\n|\n/g,"
"),Xe.debug("vertexText"+p);const v={isNode:d,label:ZF(p).replace(/fa[blrs]?:fa-[\w-]+/g,y=>``),labelStyle:s.replace("fill:","color:")};return OQt(v)}else{const v=document.createElementNS("http://www.w3.org/2000/svg","text");v.setAttribute("style",s.replace("color:","fill:"));let b=[];typeof p=="string"?b=p.split(/\\n|\n|/gi):Array.isArray(p)?b=p:b=[];for(const y of b){const T=document.createElementNS("http://www.w3.org/2000/svg","tspan");T.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),T.setAttribute("dy","1em"),T.setAttribute("x","0"),u?T.setAttribute("class","title-row"):T.setAttribute("class","row"),T.textContent=y.trim(),v.appendChild(T)}return v}},NQt={};function PQt(i,s){const u=s||NQt,d=typeof u.includeImageAlt=="boolean"?u.includeImageAlt:!0,p=typeof u.includeHtml=="boolean"?u.includeHtml:!0;return $Ve(i,d,p)}function $Ve(i,s,u){if(BQt(i)){if("value"in i)return i.type==="html"&&!u?"":i.value;if(s&&"alt"in i&&i.alt)return i.alt;if("children"in i)return zVe(i.children,s,u)}return Array.isArray(i)?zVe(i,s,u):""}function zVe(i,s,u){const d=[];let p=-1;for(;++pp?0:p+s:s=s>p?p:s,u=u>0?u:0,d.length<1e4)b=Array.from(d),b.unshift(s,u),i.splice(...b);else for(u&&i.splice(s,u);v0?(t5(i,i.length,0,s),i):s}const qVe={}.hasOwnProperty;function FQt(i){const s={};let u=-1;for(;++ub))return;const se=s.events.length;let de=se,X,ge;for(;de--;)if(s.events[de][0]==="exit"&&s.events[de][1].type==="chunkFlow"){if(X){ge=s.events[de][1].end;break}X=!0}for(ie(d),ne=se;nepe;){const ae=u[be];s.containerState=ae[1],ae[0].exit.call(s,i)}u.length=pe}function oe(){p.write([null]),v=void 0,p=void 0,s.containerState._closeFlow=void 0}}function XQt(i,s,u){return Kl(i,i.attempt(this.parser.constructs.document,s,u),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function VVe(i){if(i===null||z2(i)||UQt(i))return 1;if(VQt(i))return 2}function Lme(i,s,u){const d=[];let p=-1;for(;++p1&&i[u][1].end.offset-i[u][1].start.offset>1?2:1;const P=Object.assign({},i[d][1].end),R=Object.assign({},i[u][1].start);UVe(P,-T),UVe(R,T),b={type:T>1?"strongSequence":"emphasisSequence",start:P,end:Object.assign({},i[d][1].end)},y={type:T>1?"strongSequence":"emphasisSequence",start:Object.assign({},i[u][1].start),end:R},v={type:T>1?"strongText":"emphasisText",start:Object.assign({},i[d][1].end),end:Object.assign({},i[u][1].start)},p={type:T>1?"strong":"emphasis",start:Object.assign({},b.start),end:Object.assign({},y.end)},i[d][1].end=Object.assign({},b.start),i[u][1].start=Object.assign({},y.end),_=[],i[d][1].end.offset-i[d][1].start.offset&&(_=zv(_,[["enter",i[d][1],s],["exit",i[d][1],s]])),_=zv(_,[["enter",p,s],["enter",b,s],["exit",b,s],["enter",v,s]]),_=zv(_,Lme(s.parser.constructs.insideSpan.null,i.slice(d+1,u),s)),_=zv(_,[["exit",v,s],["enter",y,s],["exit",y,s],["exit",p,s]]),i[u][1].end.offset-i[u][1].start.offset?(A=2,_=zv(_,[["enter",i[u][1],s],["exit",i[u][1],s]])):A=0,t5(i,d-1,u-d+3,_),u=d+_.length-A-2;break}}for(u=-1;++u0&&Iu(ne)?Kl(i,oe,"linePrefix",v+1)(ne):oe(ne)}function oe(ne){return ne===null||so(ne)?i.check(XVe,K,be)(ne):(i.enter("codeFlowValue"),pe(ne))}function pe(ne){return ne===null||so(ne)?(i.exit("codeFlowValue"),oe(ne)):(i.consume(ne),pe)}function be(ne){return i.exit("codeFenced"),s(ne)}function ae(ne,se,de){let X=0;return ge;function ge(Pe){return ne.enter("lineEnding"),ne.consume(Pe),ne.exit("lineEnding"),W}function W(Pe){return ne.enter("codeFencedFence"),Iu(Pe)?Kl(ne,xe,"linePrefix",d.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(Pe):xe(Pe)}function xe(Pe){return Pe===y?(ne.enter("codeFencedFenceSequence"),U(Pe)):de(Pe)}function U(Pe){return Pe===y?(X++,ne.consume(Pe),U):X>=b?(ne.exit("codeFencedFenceSequence"),Iu(Pe)?Kl(ne,Fe,"whitespace")(Pe):Fe(Pe)):de(Pe)}function Fe(Pe){return Pe===null||so(Pe)?(ne.exit("codeFencedFence"),se(Pe)):de(Pe)}}}function cJt(i,s,u){const d=this;return p;function p(b){return b===null?u(b):(i.enter("lineEnding"),i.consume(b),i.exit("lineEnding"),v)}function v(b){return d.parser.lazy[d.now().line]?u(b):s(b)}}const Ime={name:"codeIndented",tokenize:lJt},uJt={tokenize:hJt,partial:!0};function lJt(i,s,u){const d=this;return p;function p(_){return i.enter("codeIndented"),Kl(i,v,"linePrefix",4+1)(_)}function v(_){const A=d.events[d.events.length-1];return A&&A[1].type==="linePrefix"&&A[2].sliceSerialize(A[1],!0).length>=4?b(_):u(_)}function b(_){return _===null?T(_):so(_)?i.attempt(uJt,b,T)(_):(i.enter("codeFlowValue"),y(_))}function y(_){return _===null||so(_)?(i.exit("codeFlowValue"),b(_)):(i.consume(_),y)}function T(_){return i.exit("codeIndented"),s(_)}}function hJt(i,s,u){const d=this;return p;function p(b){return d.parser.lazy[d.now().line]?u(b):so(b)?(i.enter("lineEnding"),i.consume(b),i.exit("lineEnding"),p):Kl(i,v,"linePrefix",4+1)(b)}function v(b){const y=d.events[d.events.length-1];return y&&y[1].type==="linePrefix"&&y[2].sliceSerialize(y[1],!0).length>=4?s(b):so(b)?p(b):u(b)}}const fJt={name:"codeText",tokenize:pJt,resolve:dJt,previous:gJt};function dJt(i){let s=i.length-4,u=3,d,p;if((i[u][1].type==="lineEnding"||i[u][1].type==="space")&&(i[s][1].type==="lineEnding"||i[s][1].type==="space")){for(d=u;++d=4?s(b):i.interrupt(d.parser.constructs.flow,u,s)(b)}}function ZVe(i,s,u,d,p,v,b,y,T){const _=T||Number.POSITIVE_INFINITY;let A=0;return P;function P(ie){return ie===60?(i.enter(d),i.enter(p),i.enter(v),i.consume(ie),i.exit(v),R):ie===null||ie===32||ie===41||_me(ie)?u(ie):(i.enter(d),i.enter(b),i.enter(y),i.enter("chunkString",{contentType:"string"}),K(ie))}function R(ie){return ie===62?(i.enter(v),i.consume(ie),i.exit(v),i.exit(p),i.exit(d),s):(i.enter(y),i.enter("chunkString",{contentType:"string"}),F(ie))}function F(ie){return ie===62?(i.exit("chunkString"),i.exit(y),R(ie)):ie===null||ie===60||so(ie)?u(ie):(i.consume(ie),ie===92?j:F)}function j(ie){return ie===60||ie===62||ie===92?(i.consume(ie),F):F(ie)}function K(ie){return!A&&(ie===null||ie===41||z2(ie))?(i.exit("chunkString"),i.exit(y),i.exit(b),i.exit(d),s(ie)):A<_&&ie===40?(i.consume(ie),A++,K):ie===41?(i.consume(ie),A--,K):ie===null||ie===32||ie===40||_me(ie)?u(ie):(i.consume(ie),ie===92?ee:K)}function ee(ie){return ie===40||ie===41||ie===92?(i.consume(ie),K):K(ie)}}function eUe(i,s,u,d,p,v){const b=this;let y=0,T;return _;function _(F){return i.enter(d),i.enter(p),i.consume(F),i.exit(p),i.enter(v),A}function A(F){return y>999||F===null||F===91||F===93&&!T||F===94&&!y&&"_hiddenFootnoteSupport"in b.parser.constructs?u(F):F===93?(i.exit(v),i.enter(p),i.consume(F),i.exit(p),i.exit(d),s):so(F)?(i.enter("lineEnding"),i.consume(F),i.exit("lineEnding"),A):(i.enter("chunkString",{contentType:"string"}),P(F))}function P(F){return F===null||F===91||F===93||so(F)||y++>999?(i.exit("chunkString"),A(F)):(i.consume(F),T||(T=!Iu(F)),F===92?R:P)}function R(F){return F===91||F===92||F===93?(i.consume(F),y++,P):P(F)}}function tUe(i,s,u,d,p,v){let b;return y;function y(R){return R===34||R===39||R===40?(i.enter(d),i.enter(p),i.consume(R),i.exit(p),b=R===40?41:R,T):u(R)}function T(R){return R===b?(i.enter(p),i.consume(R),i.exit(p),i.exit(d),s):(i.enter(v),_(R))}function _(R){return R===b?(i.exit(v),T(b)):R===null?u(R):so(R)?(i.enter("lineEnding"),i.consume(R),i.exit("lineEnding"),Kl(i,_,"linePrefix")):(i.enter("chunkString",{contentType:"string"}),A(R))}function A(R){return R===b||R===null||so(R)?(i.exit("chunkString"),_(R)):(i.consume(R),R===92?P:A)}function P(R){return R===b||R===92?(i.consume(R),A):A(R)}}function LR(i,s){let u;return d;function d(p){return so(p)?(i.enter("lineEnding"),i.consume(p),i.exit("lineEnding"),u=!0,d):Iu(p)?Kl(i,d,u?"linePrefix":"lineSuffix")(p):s(p)}}function HD(i){return i.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const kJt={name:"definition",tokenize:TJt},EJt={tokenize:CJt,partial:!0};function TJt(i,s,u){const d=this;let p;return v;function v(F){return i.enter("definition"),b(F)}function b(F){return eUe.call(d,i,y,u,"definitionLabel","definitionLabelMarker","definitionLabelString")(F)}function y(F){return p=HD(d.sliceSerialize(d.events[d.events.length-1][1]).slice(1,-1)),F===58?(i.enter("definitionMarker"),i.consume(F),i.exit("definitionMarker"),T):u(F)}function T(F){return z2(F)?LR(i,_)(F):_(F)}function _(F){return ZVe(i,A,u,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(F)}function A(F){return i.attempt(EJt,P,P)(F)}function P(F){return Iu(F)?Kl(i,R,"whitespace")(F):R(F)}function R(F){return F===null||so(F)?(i.exit("definition"),d.parser.defined.push(p),s(F)):u(F)}}function CJt(i,s,u){return d;function d(y){return z2(y)?LR(i,p)(y):u(y)}function p(y){return tUe(i,v,u,"definitionTitle","definitionTitleMarker","definitionTitleString")(y)}function v(y){return Iu(y)?Kl(i,b,"whitespace")(y):b(y)}function b(y){return y===null||so(y)?s(y):u(y)}}const SJt={name:"hardBreakEscape",tokenize:_Jt};function _Jt(i,s,u){return d;function d(v){return i.enter("hardBreakEscape"),i.consume(v),p}function p(v){return so(v)?(i.exit("hardBreakEscape"),s(v)):u(v)}}const AJt={name:"headingAtx",tokenize:MJt,resolve:LJt};function LJt(i,s){let u=i.length-2,d=3,p,v;return i[d][1].type==="whitespace"&&(d+=2),u-2>d&&i[u][1].type==="whitespace"&&(u-=2),i[u][1].type==="atxHeadingSequence"&&(d===u-1||u-4>d&&i[u-2][1].type==="whitespace")&&(u-=d+1===u?2:4),u>d&&(p={type:"atxHeadingText",start:i[d][1].start,end:i[u][1].end},v={type:"chunkText",start:i[d][1].start,end:i[u][1].end,contentType:"text"},t5(i,d,u-d+1,[["enter",p,s],["enter",v,s],["exit",v,s],["exit",p,s]])),i}function MJt(i,s,u){let d=0;return p;function p(A){return i.enter("atxHeading"),v(A)}function v(A){return i.enter("atxHeadingSequence"),b(A)}function b(A){return A===35&&d++<6?(i.consume(A),b):A===null||z2(A)?(i.exit("atxHeadingSequence"),y(A)):u(A)}function y(A){return A===35?(i.enter("atxHeadingSequence"),T(A)):A===null||so(A)?(i.exit("atxHeading"),s(A)):Iu(A)?Kl(i,y,"whitespace")(A):(i.enter("atxHeadingText"),_(A))}function T(A){return A===35?(i.consume(A),T):(i.exit("atxHeadingSequence"),y(A))}function _(A){return A===null||A===35||z2(A)?(i.exit("atxHeadingText"),y(A)):(i.consume(A),_)}}const DJt=["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","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],nUe=["pre","script","style","textarea"],IJt={name:"htmlFlow",tokenize:BJt,resolveTo:PJt,concrete:!0},OJt={tokenize:RJt,partial:!0},NJt={tokenize:FJt,partial:!0};function PJt(i){let s=i.length;for(;s--&&!(i[s][0]==="enter"&&i[s][1].type==="htmlFlow"););return s>1&&i[s-2][1].type==="linePrefix"&&(i[s][1].start=i[s-2][1].start,i[s+1][1].start=i[s-2][1].start,i.splice(s-2,2)),i}function BJt(i,s,u){const d=this;let p,v,b,y,T;return _;function _(Ne){return A(Ne)}function A(Ne){return i.enter("htmlFlow"),i.enter("htmlFlowData"),i.consume(Ne),P}function P(Ne){return Ne===33?(i.consume(Ne),R):Ne===47?(i.consume(Ne),v=!0,K):Ne===63?(i.consume(Ne),p=3,d.interrupt?s:ke):n5(Ne)?(i.consume(Ne),b=String.fromCharCode(Ne),ee):u(Ne)}function R(Ne){return Ne===45?(i.consume(Ne),p=2,F):Ne===91?(i.consume(Ne),p=5,y=0,j):n5(Ne)?(i.consume(Ne),p=4,d.interrupt?s:ke):u(Ne)}function F(Ne){return Ne===45?(i.consume(Ne),d.interrupt?s:ke):u(Ne)}function j(Ne){const gn="CDATA[";return Ne===gn.charCodeAt(y++)?(i.consume(Ne),y===gn.length?d.interrupt?s:xe:j):u(Ne)}function K(Ne){return n5(Ne)?(i.consume(Ne),b=String.fromCharCode(Ne),ee):u(Ne)}function ee(Ne){if(Ne===null||Ne===47||Ne===62||z2(Ne)){const gn=Ne===47,_t=b.toLowerCase();return!gn&&!v&&nUe.includes(_t)?(p=1,d.interrupt?s(Ne):xe(Ne)):DJt.includes(b.toLowerCase())?(p=6,gn?(i.consume(Ne),ie):d.interrupt?s(Ne):xe(Ne)):(p=7,d.interrupt&&!d.parser.lazy[d.now().line]?u(Ne):v?oe(Ne):pe(Ne))}return Ne===45||H3(Ne)?(i.consume(Ne),b+=String.fromCharCode(Ne),ee):u(Ne)}function ie(Ne){return Ne===62?(i.consume(Ne),d.interrupt?s:xe):u(Ne)}function oe(Ne){return Iu(Ne)?(i.consume(Ne),oe):ge(Ne)}function pe(Ne){return Ne===47?(i.consume(Ne),ge):Ne===58||Ne===95||n5(Ne)?(i.consume(Ne),be):Iu(Ne)?(i.consume(Ne),pe):ge(Ne)}function be(Ne){return Ne===45||Ne===46||Ne===58||Ne===95||H3(Ne)?(i.consume(Ne),be):ae(Ne)}function ae(Ne){return Ne===61?(i.consume(Ne),ne):Iu(Ne)?(i.consume(Ne),ae):pe(Ne)}function ne(Ne){return Ne===null||Ne===60||Ne===61||Ne===62||Ne===96?u(Ne):Ne===34||Ne===39?(i.consume(Ne),T=Ne,se):Iu(Ne)?(i.consume(Ne),ne):de(Ne)}function se(Ne){return Ne===T?(i.consume(Ne),T=null,X):Ne===null||so(Ne)?u(Ne):(i.consume(Ne),se)}function de(Ne){return Ne===null||Ne===34||Ne===39||Ne===47||Ne===60||Ne===61||Ne===62||Ne===96||z2(Ne)?ae(Ne):(i.consume(Ne),de)}function X(Ne){return Ne===47||Ne===62||Iu(Ne)?pe(Ne):u(Ne)}function ge(Ne){return Ne===62?(i.consume(Ne),W):u(Ne)}function W(Ne){return Ne===null||so(Ne)?xe(Ne):Iu(Ne)?(i.consume(Ne),W):u(Ne)}function xe(Ne){return Ne===45&&p===2?(i.consume(Ne),je):Ne===60&&p===1?(i.consume(Ne),Ie):Ne===62&&p===4?(i.consume(Ne),Ke):Ne===63&&p===3?(i.consume(Ne),ke):Ne===93&&p===5?(i.consume(Ne),Ce):so(Ne)&&(p===6||p===7)?(i.exit("htmlFlowData"),i.check(OJt,Ft,U)(Ne)):Ne===null||so(Ne)?(i.exit("htmlFlowData"),U(Ne)):(i.consume(Ne),xe)}function U(Ne){return i.check(NJt,Fe,Ft)(Ne)}function Fe(Ne){return i.enter("lineEnding"),i.consume(Ne),i.exit("lineEnding"),Pe}function Pe(Ne){return Ne===null||so(Ne)?U(Ne):(i.enter("htmlFlowData"),xe(Ne))}function je(Ne){return Ne===45?(i.consume(Ne),ke):xe(Ne)}function Ie(Ne){return Ne===47?(i.consume(Ne),b="",Se):xe(Ne)}function Se(Ne){if(Ne===62){const gn=b.toLowerCase();return nUe.includes(gn)?(i.consume(Ne),Ke):xe(Ne)}return n5(Ne)&&b.length<8?(i.consume(Ne),b+=String.fromCharCode(Ne),Se):xe(Ne)}function Ce(Ne){return Ne===93?(i.consume(Ne),ke):xe(Ne)}function ke(Ne){return Ne===62?(i.consume(Ne),Ke):Ne===45&&p===2?(i.consume(Ne),ke):xe(Ne)}function Ke(Ne){return Ne===null||so(Ne)?(i.exit("htmlFlowData"),Ft(Ne)):(i.consume(Ne),Ke)}function Ft(Ne){return i.exit("htmlFlow"),s(Ne)}}function FJt(i,s,u){const d=this;return p;function p(b){return so(b)?(i.enter("lineEnding"),i.consume(b),i.exit("lineEnding"),v):u(b)}function v(b){return d.parser.lazy[d.now().line]?u(b):s(b)}}function RJt(i,s,u){return d;function d(p){return i.enter("lineEnding"),i.consume(p),i.exit("lineEnding"),i.attempt(YQ,s,u)}}const jJt={name:"htmlText",tokenize:$Jt};function $Jt(i,s,u){const d=this;let p,v,b;return y;function y(ke){return i.enter("htmlText"),i.enter("htmlTextData"),i.consume(ke),T}function T(ke){return ke===33?(i.consume(ke),_):ke===47?(i.consume(ke),ae):ke===63?(i.consume(ke),pe):n5(ke)?(i.consume(ke),de):u(ke)}function _(ke){return ke===45?(i.consume(ke),A):ke===91?(i.consume(ke),v=0,j):n5(ke)?(i.consume(ke),oe):u(ke)}function A(ke){return ke===45?(i.consume(ke),F):u(ke)}function P(ke){return ke===null?u(ke):ke===45?(i.consume(ke),R):so(ke)?(b=P,Ie(ke)):(i.consume(ke),P)}function R(ke){return ke===45?(i.consume(ke),F):P(ke)}function F(ke){return ke===62?je(ke):ke===45?R(ke):P(ke)}function j(ke){const Ke="CDATA[";return ke===Ke.charCodeAt(v++)?(i.consume(ke),v===Ke.length?K:j):u(ke)}function K(ke){return ke===null?u(ke):ke===93?(i.consume(ke),ee):so(ke)?(b=K,Ie(ke)):(i.consume(ke),K)}function ee(ke){return ke===93?(i.consume(ke),ie):K(ke)}function ie(ke){return ke===62?je(ke):ke===93?(i.consume(ke),ie):K(ke)}function oe(ke){return ke===null||ke===62?je(ke):so(ke)?(b=oe,Ie(ke)):(i.consume(ke),oe)}function pe(ke){return ke===null?u(ke):ke===63?(i.consume(ke),be):so(ke)?(b=pe,Ie(ke)):(i.consume(ke),pe)}function be(ke){return ke===62?je(ke):pe(ke)}function ae(ke){return n5(ke)?(i.consume(ke),ne):u(ke)}function ne(ke){return ke===45||H3(ke)?(i.consume(ke),ne):se(ke)}function se(ke){return so(ke)?(b=se,Ie(ke)):Iu(ke)?(i.consume(ke),se):je(ke)}function de(ke){return ke===45||H3(ke)?(i.consume(ke),de):ke===47||ke===62||z2(ke)?X(ke):u(ke)}function X(ke){return ke===47?(i.consume(ke),je):ke===58||ke===95||n5(ke)?(i.consume(ke),ge):so(ke)?(b=X,Ie(ke)):Iu(ke)?(i.consume(ke),X):je(ke)}function ge(ke){return ke===45||ke===46||ke===58||ke===95||H3(ke)?(i.consume(ke),ge):W(ke)}function W(ke){return ke===61?(i.consume(ke),xe):so(ke)?(b=W,Ie(ke)):Iu(ke)?(i.consume(ke),W):X(ke)}function xe(ke){return ke===null||ke===60||ke===61||ke===62||ke===96?u(ke):ke===34||ke===39?(i.consume(ke),p=ke,U):so(ke)?(b=xe,Ie(ke)):Iu(ke)?(i.consume(ke),xe):(i.consume(ke),Fe)}function U(ke){return ke===p?(i.consume(ke),p=void 0,Pe):ke===null?u(ke):so(ke)?(b=U,Ie(ke)):(i.consume(ke),U)}function Fe(ke){return ke===null||ke===34||ke===39||ke===60||ke===61||ke===96?u(ke):ke===47||ke===62||z2(ke)?X(ke):(i.consume(ke),Fe)}function Pe(ke){return ke===47||ke===62||z2(ke)?X(ke):u(ke)}function je(ke){return ke===62?(i.consume(ke),i.exit("htmlTextData"),i.exit("htmlText"),s):u(ke)}function Ie(ke){return i.exit("htmlTextData"),i.enter("lineEnding"),i.consume(ke),i.exit("lineEnding"),Se}function Se(ke){return Iu(ke)?Kl(i,Ce,"linePrefix",d.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(ke):Ce(ke)}function Ce(ke){return i.enter("htmlTextData"),b(ke)}}const Ome={name:"labelEnd",tokenize:GJt,resolveTo:UJt,resolveAll:VJt},zJt={tokenize:KJt},qJt={tokenize:WJt},HJt={tokenize:YJt};function VJt(i){let s=-1;for(;++s=3&&(_===null||so(_))?(i.exit("thematicBreak"),s(_)):u(_)}function T(_){return _===p?(i.consume(_),d++,T):(i.exit("thematicBreakSequence"),Iu(_)?Kl(i,y,"whitespace")(_):y(_))}}const q2={name:"list",tokenize:iZt,continuation:{tokenize:sZt},exit:oZt},nZt={tokenize:cZt,partial:!0},rZt={tokenize:aZt,partial:!0};function iZt(i,s,u){const d=this,p=d.events[d.events.length-1];let v=p&&p[1].type==="linePrefix"?p[2].sliceSerialize(p[1],!0).length:0,b=0;return y;function y(F){const j=d.containerState.type||(F===42||F===43||F===45?"listUnordered":"listOrdered");if(j==="listUnordered"?!d.containerState.marker||F===d.containerState.marker:Ame(F)){if(d.containerState.type||(d.containerState.type=j,i.enter(j,{_container:!0})),j==="listUnordered")return i.enter("listItemPrefix"),F===42||F===45?i.check(XQ,u,_)(F):_(F);if(!d.interrupt||F===49)return i.enter("listItemPrefix"),i.enter("listItemValue"),T(F)}return u(F)}function T(F){return Ame(F)&&++b<10?(i.consume(F),T):(!d.interrupt||b<2)&&(d.containerState.marker?F===d.containerState.marker:F===41||F===46)?(i.exit("listItemValue"),_(F)):u(F)}function _(F){return i.enter("listItemMarker"),i.consume(F),i.exit("listItemMarker"),d.containerState.marker=d.containerState.marker||F,i.check(YQ,d.interrupt?u:A,i.attempt(nZt,R,P))}function A(F){return d.containerState.initialBlankLine=!0,v++,R(F)}function P(F){return Iu(F)?(i.enter("listItemPrefixWhitespace"),i.consume(F),i.exit("listItemPrefixWhitespace"),R):u(F)}function R(F){return d.containerState.size=v+d.sliceSerialize(i.exit("listItemPrefix"),!0).length,s(F)}}function sZt(i,s,u){const d=this;return d.containerState._closeFlow=void 0,i.check(YQ,p,v);function p(y){return d.containerState.furtherBlankLines=d.containerState.furtherBlankLines||d.containerState.initialBlankLine,Kl(i,s,"listItemIndent",d.containerState.size+1)(y)}function v(y){return d.containerState.furtherBlankLines||!Iu(y)?(d.containerState.furtherBlankLines=void 0,d.containerState.initialBlankLine=void 0,b(y)):(d.containerState.furtherBlankLines=void 0,d.containerState.initialBlankLine=void 0,i.attempt(rZt,s,b)(y))}function b(y){return d.containerState._closeFlow=!0,d.interrupt=void 0,Kl(i,i.attempt(q2,s,u),"linePrefix",d.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(y)}}function aZt(i,s,u){const d=this;return Kl(i,p,"listItemIndent",d.containerState.size+1);function p(v){const b=d.events[d.events.length-1];return b&&b[1].type==="listItemIndent"&&b[2].sliceSerialize(b[1],!0).length===d.containerState.size?s(v):u(v)}}function oZt(i){i.exit(this.containerState.type)}function cZt(i,s,u){const d=this;return Kl(i,p,"listItemPrefixWhitespace",d.parser.constructs.disable.null.includes("codeIndented")?void 0:4+1);function p(v){const b=d.events[d.events.length-1];return!Iu(v)&&b&&b[1].type==="listItemPrefixWhitespace"?s(v):u(v)}}const rUe={name:"setextUnderline",tokenize:lZt,resolveTo:uZt};function uZt(i,s){let u=i.length,d,p,v;for(;u--;)if(i[u][0]==="enter"){if(i[u][1].type==="content"){d=u;break}i[u][1].type==="paragraph"&&(p=u)}else i[u][1].type==="content"&&i.splice(u,1),!v&&i[u][1].type==="definition"&&(v=u);const b={type:"setextHeading",start:Object.assign({},i[p][1].start),end:Object.assign({},i[i.length-1][1].end)};return i[p][1].type="setextHeadingText",v?(i.splice(p,0,["enter",b,s]),i.splice(v+1,0,["exit",i[d][1],s]),i[d][1].end=Object.assign({},i[v][1].end)):i[d][1]=b,i.push(["exit",b,s]),i}function lZt(i,s,u){const d=this;let p;return v;function v(_){let A=d.events.length,P;for(;A--;)if(d.events[A][1].type!=="lineEnding"&&d.events[A][1].type!=="linePrefix"&&d.events[A][1].type!=="content"){P=d.events[A][1].type==="paragraph";break}return!d.parser.lazy[d.now().line]&&(d.interrupt||P)?(i.enter("setextHeadingLine"),p=_,b(_)):u(_)}function b(_){return i.enter("setextHeadingLineSequence"),y(_)}function y(_){return _===p?(i.consume(_),y):(i.exit("setextHeadingLineSequence"),Iu(_)?Kl(i,T,"lineSuffix")(_):T(_))}function T(_){return _===null||so(_)?(i.exit("setextHeadingLine"),s(_)):u(_)}}const hZt={tokenize:fZt};function fZt(i){const s=this,u=i.attempt(YQ,d,i.attempt(this.parser.constructs.flowInitial,p,Kl(i,i.attempt(this.parser.constructs.flow,p,i.attempt(mJt,p)),"linePrefix")));return u;function d(v){if(v===null){i.consume(v);return}return i.enter("lineEndingBlank"),i.consume(v),i.exit("lineEndingBlank"),s.currentConstruct=void 0,u}function p(v){if(v===null){i.consume(v);return}return i.enter("lineEnding"),i.consume(v),i.exit("lineEnding"),s.currentConstruct=void 0,u}}const dZt={resolveAll:sUe()},gZt=iUe("string"),pZt=iUe("text");function iUe(i){return{tokenize:s,resolveAll:sUe(i==="text"?bZt:void 0)};function s(u){const d=this,p=this.parser.constructs[i],v=u.attempt(p,b,y);return b;function b(A){return _(A)?v(A):y(A)}function y(A){if(A===null){u.consume(A);return}return u.enter("data"),u.consume(A),T}function T(A){return _(A)?(u.exit("data"),v(A)):(u.consume(A),T)}function _(A){if(A===null)return!0;const P=p[A];let R=-1;if(P)for(;++R-1){const y=b[0];typeof y=="string"?b[0]=y.slice(d):b.shift()}v>0&&b.push(i[p].slice(0,v))}return b}function wZt(i,s){let u=-1;const d=[];let p;for(;++u13&&u<32||u>126&&u<160||u>55295&&u<57344||u>64975&&u<65008||(u&65535)===65535||(u&65535)===65534||u>1114111?"�":String.fromCharCode(u)}const TZt=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function CZt(i){return i.replace(TZt,SZt)}function SZt(i,s,u){if(s)return s;if(u.charCodeAt(0)===35){const p=u.charCodeAt(1),v=p===120||p===88;return oUe(u.slice(v?2:1),v?16:10)}return Dme(u)||i}function QQ(i){return!i||typeof i!="object"?"":"position"in i||"type"in i?cUe(i.position):"start"in i||"end"in i?cUe(i):"line"in i||"column"in i?Pme(i):""}function Pme(i){return uUe(i&&i.line)+":"+uUe(i&&i.column)}function cUe(i){return Pme(i&&i.start)+"-"+Pme(i&&i.end)}function uUe(i){return i&&typeof i=="number"?i:1}const lUe={}.hasOwnProperty,hUe=function(i,s,u){return typeof s!="string"&&(u=s,s=void 0),_Zt(u)(EZt(xZt(u).document().write(kZt()(i,s,!0))))};function _Zt(i){const s={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:y(Ma),autolinkProtocol:W,autolinkEmail:W,atxHeading:y(zr),blockQuote:y(Qe),characterEscape:W,characterReference:W,codeFenced:y(Dt),codeFencedFenceInfo:T,codeFencedFenceMeta:T,codeIndented:y(Dt,T),codeText:y(kt,T),codeTextData:W,data:W,codeFlowValue:W,definition:y(On),definitionDestinationString:T,definitionLabelString:T,definitionTitleString:T,emphasis:y(ht),hardBreakEscape:y(yt),hardBreakTrailing:y(yt),htmlFlow:y(ji,T),htmlFlowData:W,htmlText:y(ji,T),htmlTextData:W,image:y(xi),label:T,link:y(Ma),listItem:y(ao),listItemValue:j,listOrdered:y(zs,F),listUnordered:y(zs),paragraph:y(Tr),reference:_t,referenceString:T,resourceDestinationString:T,resourceTitleString:T,setextHeading:y(zr),strong:y(Fn),thematicBreak:y(Un)},exit:{atxHeading:A(),atxHeadingSequence:se,autolink:A(),autolinkEmail:Pt,autolinkProtocol:xt,blockQuote:A(),characterEscapeValue:xe,characterReferenceMarkerHexadecimal:Gt,characterReferenceMarkerNumeric:Gt,characterReferenceValue:ln,codeFenced:A(oe),codeFencedFence:ie,codeFencedFenceInfo:K,codeFencedFenceMeta:ee,codeFlowValue:xe,codeIndented:A(pe),codeText:A(Ie),codeTextData:xe,data:xe,definition:A(),definitionDestinationString:ne,definitionLabelString:be,definitionTitleString:ae,emphasis:A(),hardBreakEscape:A(Fe),hardBreakTrailing:A(Fe),htmlFlow:A(Pe),htmlFlowData:xe,htmlText:A(je),htmlTextData:xe,image:A(Ce),label:Ke,labelText:ke,lineEnding:U,link:A(Se),listItem:A(),listOrdered:A(),listUnordered:A(),paragraph:A(),referenceString:Et,resourceDestinationString:Ft,resourceTitleString:Ne,resource:gn,setextHeading:A(ge),setextHeadingLineSequence:X,setextHeadingText:de,strong:A(),thematicBreak:A()}};fUe(s,(i||{}).mdastExtensions||[]);const u={};return d;function d(At){let wt={type:"root",children:[]};const on={stack:[wt],tokenStack:[],config:s,enter:_,exit:P,buffer:T,resume:R,setData:v,getData:b},fn=[];let An=-1;for(;++An0){const oo=on.tokenStack[on.tokenStack.length-1];(oo[1]||dUe).call(on,void 0,oo[0])}for(wt.position={start:N9(At.length>0?At[0][1].start:{line:1,column:1,offset:0}),end:N9(At.length>0?At[At.length-2][1].end:{line:1,column:1,offset:0})},An=-1;++An{A!==0&&(p++,d.push([])),_.split(" ").forEach(P=>{P&&d[p].push({content:P,type:y})})}):(b.type==="strong"||b.type==="emphasis")&&b.children.forEach(T=>{v(T,b.type)})}return u.forEach(b=>{b.type==="paragraph"&&b.children.forEach(y=>{v(y)})}),d}function DZt(i){const{children:s}=hUe(i);function u(d){return d.type==="text"?d.value.replace(/\n/g,"
"):d.type==="strong"?`${d.children.map(u).join("")}`:d.type==="emphasis"?`${d.children.map(u).join("")}`:d.type==="paragraph"?`

${d.children.map(u).join("")}

`:`Unsupported markdown: ${d.type}`}return s.map(u).join("")}function IZt(i){return Intl.Segmenter?[...new Intl.Segmenter().segment(i)].map(s=>s.segment):[...i]}function OZt(i,s){const u=IZt(s.content);return gUe(i,[],u,s.type)}function gUe(i,s,u,d){if(u.length===0)return[{content:s.join(""),type:d},{content:"",type:d}];const[p,...v]=u,b=[...s,p];return i([{content:b.join(""),type:d}])?gUe(i,b,v,d):(s.length===0&&p&&(s.push(p),u.shift()),[{content:s.join(""),type:d},{content:u.join(""),type:d}])}function NZt(i,s){if(i.some(({content:u})=>u.includes(` +`)))throw new Error("splitLineToFitWidth does not support newlines in the line");return Bme(i,s)}function Bme(i,s,u=[],d=[]){if(i.length===0)return d.length>0&&u.push(d),u.length>0?u:[];let p="";i[0].content===" "&&(p=" ",i.shift());const v=i.shift()??{content:" ",type:"normal"},b=[...d];if(p!==""&&b.push({content:p,type:"normal"}),b.push(v),s(b))return Bme(i,s,u,b);if(d.length>0)u.push(d),i.unshift(v);else if(v.content){const[y,T]=OZt(s,v);u.push([y]),T.content&&i.unshift(T)}return Bme(i,s,u)}function PZt(i,s){s&&i.attr("style",s)}function BZt(i,s,u,d,p=!1){const v=i.append("foreignObject"),b=v.append("xhtml:div"),y=s.label,T=s.isNode?"nodeLabel":"edgeLabel";b.html(` + "+y+""),PZt(b,s.labelStyle),b.style("display","table-cell"),b.style("white-space","nowrap"),b.style("max-width",u+"px"),b.attr("xmlns","http://www.w3.org/1999/xhtml"),p&&b.attr("class","labelBkg");let _=b.node().getBoundingClientRect();return _.width===u&&(b.style("display","table"),b.style("white-space","break-spaces"),b.style("width",u+"px"),_=b.node().getBoundingClientRect()),v.style("width",_.width),v.style("height",_.height),v.node()}function Fme(i,s,u){return i.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",s*u-.1+"em").attr("dy",u+"em")}function FZt(i,s,u){const d=i.append("text"),p=Fme(d,1,s);Rme(p,u);const v=p.node().getComputedTextLength();return d.remove(),v}function RZt(i,s,u){var b;const d=i.append("text"),p=Fme(d,1,s);Rme(p,[{content:u,type:"normal"}]);const v=(b=p.node())==null?void 0:b.getBoundingClientRect();return v&&d.remove(),v}function jZt(i,s,u,d=!1){const v=s.append("g"),b=v.insert("rect").attr("class","background"),y=v.append("text").attr("y","-10.1");let T=0;for(const _ of u){const A=R=>FZt(v,1.1,R)<=i,P=A(_)?[_]:NZt(_,A);for(const R of P){const F=Fme(y,T,1.1);Rme(F,R),T++}}if(d){const _=y.node().getBBox(),A=2;return b.attr("x",-A).attr("y",-A).attr("width",_.width+2*A).attr("height",_.height+2*A),v.node()}else return y.node()}function Rme(i,s){i.text(""),s.forEach((u,d)=>{const p=i.append("tspan").attr("font-style",u.type==="emphasis"?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight",u.type==="strong"?"bold":"normal");d===0?p.text(u.content):p.text(" "+u.content)})}const JQ=(i,s="",{style:u="",isTitle:d=!1,classes:p="",useHtmlLabels:v=!0,isNode:b=!0,width:y=200,addSvgBackground:T=!1}={})=>{if(Xe.info("createText",s,u,d,p,v,b,T),v){const _=DZt(s),A={isNode:b,label:ZF(_).replace(/fa[blrs]?:fa-[\w-]+/g,R=>``),labelStyle:u.replace("fill:","color:")};return BZt(i,A,y,p,T)}else{const _=MZt(s);return jZt(y,i,_,T)}},g1=async(i,s,u,d)=>{let p;const v=s.useHtmlLabels||f1(qt().flowchart.htmlLabels);u?p=u:p="node default";const b=i.insert("g").attr("class",p).attr("id",s.domId||s.id),y=b.insert("g").attr("class","label").attr("style",s.labelStyle);let T;s.labelText===void 0?T="":T=typeof s.labelText=="string"?s.labelText:s.labelText[0];const _=y.node();let A;s.labelType==="markdown"?A=JQ(y,Yf(ZF(T),qt()),{useHtmlLabels:v,width:s.width||qt().flowchart.wrappingWidth,classes:"markdown-node-label"}):A=_.appendChild($2(Yf(ZF(T),qt()),s.labelStyle,!1,d));let P=A.getBBox();const R=s.padding/2;if(f1(qt().flowchart.htmlLabels)){const F=A.children[0],j=Ir(A),K=F.getElementsByTagName("img");if(K){const ee=T.replace(/]*>/g,"").trim()==="";await Promise.all([...K].map(ie=>new Promise(oe=>{function pe(){if(ie.style.display="flex",ie.style.flexDirection="column",ee){const be=qt().fontSize?qt().fontSize:window.getComputedStyle(document.body).fontSize,ae=5,ne=parseInt(be,10)*ae+"px";ie.style.minWidth=ne,ie.style.maxWidth=ne}else ie.style.width="100%";oe(ie)}setTimeout(()=>{ie.complete&&pe()}),ie.addEventListener("error",pe),ie.addEventListener("load",pe)})))}P=F.getBoundingClientRect(),j.attr("width",P.width),j.attr("height",P.height)}return v?y.attr("transform","translate("+-P.width/2+", "+-P.height/2+")"):y.attr("transform","translate(0, "+-P.height/2+")"),s.centerLabel&&y.attr("transform","translate("+-P.width/2+", "+-P.height/2+")"),y.insert("rect",":first-child"),{shapeSvg:b,bbox:P,halfPadding:R,label:y}},Kh=(i,s)=>{const u=s.node().getBBox();i.width=u.width,i.height=u.height};function r5(i,s,u,d){return i.insert("polygon",":first-child").attr("points",d.map(function(p){return p.x+","+p.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-s/2+","+u/2+")")}let Mo={},V3={},pUe={};const $Zt=()=>{V3={},pUe={},Mo={}},ZQ=(i,s)=>(Xe.trace("In isDescendant",s," ",i," = ",V3[s].includes(i)),!!V3[s].includes(i)),zZt=(i,s)=>(Xe.info("Descendants of ",s," is ",V3[s]),Xe.info("Edge is ",i),i.v===s||i.w===s?!1:V3[s]?V3[s].includes(i.v)||ZQ(i.v,s)||ZQ(i.w,s)||V3[s].includes(i.w):(Xe.debug("Tilt, ",s,",not in descendants"),!1)),bUe=(i,s,u,d)=>{Xe.warn("Copying children of ",i,"root",d,"data",s.node(i),d);const p=s.children(i)||[];i!==d&&p.push(i),Xe.warn("Copying (nodes) clusterId",i,"nodes",p),p.forEach(v=>{if(s.children(v).length>0)bUe(v,s,u,d);else{const b=s.node(v);Xe.info("cp ",v," to ",d," with parent ",i),u.setNode(v,b),d!==s.parent(v)&&(Xe.warn("Setting parent",v,s.parent(v)),u.setParent(v,s.parent(v))),i!==d&&v!==i?(Xe.debug("Setting parent",v,i),u.setParent(v,i)):(Xe.info("In copy ",i,"root",d,"data",s.node(i),d),Xe.debug("Not Setting parent for node=",v,"cluster!==rootId",i!==d,"node!==clusterId",v!==i));const y=s.edges(v);Xe.debug("Copying Edges",y),y.forEach(T=>{Xe.info("Edge",T);const _=s.edge(T.v,T.w,T.name);Xe.info("Edge data",_,d);try{zZt(T,d)?(Xe.info("Copying as ",T.v,T.w,_,T.name),u.setEdge(T.v,T.w,_,T.name),Xe.info("newGraph edges ",u.edges(),u.edge(u.edges()[0]))):Xe.info("Skipping copy of edge ",T.v,"-->",T.w," rootId: ",d," clusterId:",i)}catch(A){Xe.error(A)}})}Xe.debug("Removing node",v),s.removeNode(v)})},mUe=(i,s)=>{const u=s.children(i);let d=[...u];for(const p of u)pUe[p]=i,d=[...d,...mUe(p,s)];return d},MR=(i,s)=>{Xe.trace("Searching",i);const u=s.children(i);if(Xe.trace("Searching children of id ",i,u),u.length<1)return Xe.trace("This is a valid node",i),i;for(const d of u){const p=MR(d,s);if(p)return Xe.trace("Found replacement for",i," => ",p),p}},eJ=i=>!Mo[i]||!Mo[i].externalConnections?i:Mo[i]?Mo[i].id:i,qZt=(i,s)=>{if(!i||s>10){Xe.debug("Opting out, no graph ");return}else Xe.debug("Opting in, graph ");i.nodes().forEach(function(u){i.children(u).length>0&&(Xe.warn("Cluster identified",u," Replacement id in edges: ",MR(u,i)),V3[u]=mUe(u,i),Mo[u]={id:MR(u,i),clusterData:i.node(u)})}),i.nodes().forEach(function(u){const d=i.children(u),p=i.edges();d.length>0?(Xe.debug("Cluster identified",u,V3),p.forEach(v=>{if(v.v!==u&&v.w!==u){const b=ZQ(v.v,u),y=ZQ(v.w,u);b^y&&(Xe.warn("Edge: ",v," leaves cluster ",u),Xe.warn("Descendants of XXX ",u,": ",V3[u]),Mo[u].externalConnections=!0)}})):Xe.debug("Not a cluster ",u,V3)});for(let u of Object.keys(Mo)){const d=Mo[u].id,p=i.parent(d);p!==u&&Mo[p]&&!Mo[p].externalConnections&&(Mo[u].id=p)}i.edges().forEach(function(u){const d=i.edge(u);Xe.warn("Edge "+u.v+" -> "+u.w+": "+JSON.stringify(u)),Xe.warn("Edge "+u.v+" -> "+u.w+": "+JSON.stringify(i.edge(u)));let p=u.v,v=u.w;if(Xe.warn("Fix XXX",Mo,"ids:",u.v,u.w,"Translating: ",Mo[u.v]," --- ",Mo[u.w]),Mo[u.v]&&Mo[u.w]&&Mo[u.v]===Mo[u.w]){Xe.warn("Fixing and trixing link to self - removing XXX",u.v,u.w,u.name),Xe.warn("Fixing and trixing - removing XXX",u.v,u.w,u.name),p=eJ(u.v),v=eJ(u.w),i.removeEdge(u.v,u.w,u.name);const b=u.w+"---"+u.v;i.setNode(b,{domId:b,id:b,labelStyle:"",labelText:d.label,padding:0,shape:"labelRect",style:""});const y=structuredClone(d),T=structuredClone(d);y.label="",y.arrowTypeEnd="none",T.label="",y.fromCluster=u.v,T.toCluster=u.v,i.setEdge(p,b,y,u.name+"-cyclic-special"),i.setEdge(b,v,T,u.name+"-cyclic-special")}else if(Mo[u.v]||Mo[u.w]){if(Xe.warn("Fixing and trixing - removing XXX",u.v,u.w,u.name),p=eJ(u.v),v=eJ(u.w),i.removeEdge(u.v,u.w,u.name),p!==u.v){const b=i.parent(p);Mo[b].externalConnections=!0,d.fromCluster=u.v}if(v!==u.w){const b=i.parent(v);Mo[b].externalConnections=!0,d.toCluster=u.w}Xe.warn("Fix Replacing with XXX",p,v,u.name),i.setEdge(p,v,d,u.name)}}),Xe.warn("Adjusted Graph",q7(i)),vUe(i,0),Xe.trace(Mo)},vUe=(i,s)=>{if(Xe.warn("extractor - ",s,q7(i),i.children("D")),s>10){Xe.error("Bailing out");return}let u=i.nodes(),d=!1;for(const p of u){const v=i.children(p);d=d||v.length>0}if(!d){Xe.debug("Done, no node has children",i.nodes());return}Xe.debug("Nodes = ",u,s);for(const p of u)if(Xe.debug("Extracting node",p,Mo,Mo[p]&&!Mo[p].externalConnections,!i.parent(p),i.node(p),i.children("D")," Depth ",s),!Mo[p])Xe.debug("Not a cluster",p,s);else if(!Mo[p].externalConnections&&i.children(p)&&i.children(p).length>0){Xe.warn("Cluster without external connections, without a parent and with children",p,s);let b=i.graph().rankdir==="TB"?"LR":"TB";Mo[p]&&Mo[p].clusterData&&Mo[p].clusterData.dir&&(b=Mo[p].clusterData.dir,Xe.warn("Fixing dir",Mo[p].clusterData.dir,b));const y=new B0({multigraph:!0,compound:!0}).setGraph({rankdir:b,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});Xe.warn("Old graph before copy",q7(i)),bUe(p,i,y,p),i.setNode(p,{clusterNode:!0,id:p,clusterData:Mo[p].clusterData,labelText:Mo[p].labelText,graph:y}),Xe.warn("New graph after copy node: (",p,")",q7(y)),Xe.debug("Old graph after copy",q7(i))}else Xe.warn("Cluster ** ",p," **not meeting the criteria !externalConnections:",!Mo[p].externalConnections," no parent: ",!i.parent(p)," children ",i.children(p)&&i.children(p).length>0,i.children("D"),s),Xe.debug(Mo);u=i.nodes(),Xe.warn("New list of nodes",u);for(const p of u){const v=i.node(p);Xe.warn(" Now next level",p,v),v.clusterNode&&vUe(v.graph,s+1)}},wUe=(i,s)=>{if(s.length===0)return[];let u=Object.assign(s);return s.forEach(d=>{const p=i.children(d),v=wUe(i,p);u=[...u,...v]}),u},HZt=i=>wUe(i,i.children());function VZt(i,s){return i.intersect(s)}function yUe(i,s,u,d){var p=i.x,v=i.y,b=p-d.x,y=v-d.y,T=Math.sqrt(s*s*y*y+u*u*b*b),_=Math.abs(s*u*b/T);d.x0}function KZt(i,s,u){var d=i.x,p=i.y,v=[],b=Number.POSITIVE_INFINITY,y=Number.POSITIVE_INFINITY;typeof s.forEach=="function"?s.forEach(function(j){b=Math.min(b,j.x),y=Math.min(y,j.y)}):(b=Math.min(b,s.x),y=Math.min(y,s.y));for(var T=d-i.width/2-b,_=p-i.height/2-y,A=0;A1&&v.sort(function(j,K){var ee=j.x-u.x,ie=j.y-u.y,oe=Math.sqrt(ee*ee+ie*ie),pe=K.x-u.x,be=K.y-u.y,ae=Math.sqrt(pe*pe+be*be);return oe{var u=i.x,d=i.y,p=s.x-u,v=s.y-d,b=i.width/2,y=i.height/2,T,_;return Math.abs(v)*b>Math.abs(p)*y?(v<0&&(y=-y),T=v===0?0:y*p/v,_=y):(p<0&&(b=-b),T=b,_=p===0?0:b*v/p),{x:u+T,y:d+_}},yh={node:VZt,circle:UZt,ellipse:yUe,polygon:KZt,rect:DR},WZt=async(i,s)=>{s.useHtmlLabels||qt().flowchart.htmlLabels||(s.centerLabel=!0);const{shapeSvg:d,bbox:p,halfPadding:v}=await g1(i,s,"node "+s.classes,!0);Xe.info("Classes = ",s.classes);const b=d.insert("rect",":first-child");return b.attr("rx",s.rx).attr("ry",s.ry).attr("x",-p.width/2-v).attr("y",-p.height/2-v).attr("width",p.width+s.padding).attr("height",p.height+s.padding),Kh(s,b),s.intersect=function(y){return yh.rect(s,y)},d},YZt=i=>{const s=new Set;for(const u of i)switch(u){case"x":s.add("right"),s.add("left");break;case"y":s.add("up"),s.add("down");break;default:s.add(u);break}return s},XZt=(i,s,u)=>{const d=YZt(i),p=2,v=s.height+2*u.padding,b=v/p,y=s.width+2*b+u.padding,T=u.padding/2;return d.has("right")&&d.has("left")&&d.has("up")&&d.has("down")?[{x:0,y:0},{x:b,y:0},{x:y/2,y:2*T},{x:y-b,y:0},{x:y,y:0},{x:y,y:-v/3},{x:y+2*T,y:-v/2},{x:y,y:-2*v/3},{x:y,y:-v},{x:y-b,y:-v},{x:y/2,y:-v-2*T},{x:b,y:-v},{x:0,y:-v},{x:0,y:-2*v/3},{x:-2*T,y:-v/2},{x:0,y:-v/3}]:d.has("right")&&d.has("left")&&d.has("up")?[{x:b,y:0},{x:y-b,y:0},{x:y,y:-v/2},{x:y-b,y:-v},{x:b,y:-v},{x:0,y:-v/2}]:d.has("right")&&d.has("left")&&d.has("down")?[{x:0,y:0},{x:b,y:-v},{x:y-b,y:-v},{x:y,y:0}]:d.has("right")&&d.has("up")&&d.has("down")?[{x:0,y:0},{x:y,y:-b},{x:y,y:-v+b},{x:0,y:-v}]:d.has("left")&&d.has("up")&&d.has("down")?[{x:y,y:0},{x:0,y:-b},{x:0,y:-v+b},{x:y,y:-v}]:d.has("right")&&d.has("left")?[{x:b,y:0},{x:b,y:-T},{x:y-b,y:-T},{x:y-b,y:0},{x:y,y:-v/2},{x:y-b,y:-v},{x:y-b,y:-v+T},{x:b,y:-v+T},{x:b,y:-v},{x:0,y:-v/2}]:d.has("up")&&d.has("down")?[{x:y/2,y:0},{x:0,y:-T},{x:b,y:-T},{x:b,y:-v+T},{x:0,y:-v+T},{x:y/2,y:-v},{x:y,y:-v+T},{x:y-b,y:-v+T},{x:y-b,y:-T},{x:y,y:-T}]:d.has("right")&&d.has("up")?[{x:0,y:0},{x:y,y:-b},{x:0,y:-v}]:d.has("right")&&d.has("down")?[{x:0,y:0},{x:y,y:0},{x:0,y:-v}]:d.has("left")&&d.has("up")?[{x:y,y:0},{x:0,y:-b},{x:y,y:-v}]:d.has("left")&&d.has("down")?[{x:y,y:0},{x:0,y:0},{x:y,y:-v}]:d.has("right")?[{x:b,y:-T},{x:b,y:-T},{x:y-b,y:-T},{x:y-b,y:0},{x:y,y:-v/2},{x:y-b,y:-v},{x:y-b,y:-v+T},{x:b,y:-v+T},{x:b,y:-v+T}]:d.has("left")?[{x:b,y:0},{x:b,y:-T},{x:y-b,y:-T},{x:y-b,y:-v+T},{x:b,y:-v+T},{x:b,y:-v},{x:0,y:-v/2}]:d.has("up")?[{x:b,y:-T},{x:b,y:-v+T},{x:0,y:-v+T},{x:y/2,y:-v},{x:y,y:-v+T},{x:y-b,y:-v+T},{x:y-b,y:-T}]:d.has("down")?[{x:y/2,y:0},{x:0,y:-T},{x:b,y:-T},{x:b,y:-v+T},{x:y-b,y:-v+T},{x:y-b,y:-T},{x:y,y:-T}]:[{x:0,y:0}]},kUe=i=>i?" "+i:"",dm=(i,s)=>`${s||"node default"}${kUe(i.classes)} ${kUe(i.class)}`,EUe=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=d.height+s.padding,b=p+v,y=[{x:b/2,y:0},{x:b,y:-b/2},{x:b/2,y:-b},{x:0,y:-b/2}];Xe.info("Question main (Circle)");const T=r5(u,b,b,y);return T.attr("style",s.style),Kh(s,T),s.intersect=function(_){return Xe.warn("Intersect called"),yh.polygon(s,y,_)},u},QZt=(i,s)=>{const u=i.insert("g").attr("class","node default").attr("id",s.domId||s.id),d=28,p=[{x:0,y:d/2},{x:d/2,y:0},{x:0,y:-d/2},{x:-d/2,y:0}];return u.insert("polygon",":first-child").attr("points",p.map(function(b){return b.x+","+b.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),s.width=28,s.height=28,s.intersect=function(b){return yh.circle(s,14,b)},u},JZt=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=4,v=d.height+s.padding,b=v/p,y=d.width+2*b+s.padding,T=[{x:b,y:0},{x:y-b,y:0},{x:y,y:-v/2},{x:y-b,y:-v},{x:b,y:-v},{x:0,y:-v/2}],_=r5(u,y,v,T);return _.attr("style",s.style),Kh(s,_),s.intersect=function(A){return yh.polygon(s,T,A)},u},ZZt=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,void 0,!0),p=2,v=d.height+2*s.padding,b=v/p,y=d.width+2*b+s.padding,T=XZt(s.directions,d,s),_=r5(u,y,v,T);return _.attr("style",s.style),Kh(s,_),s.intersect=function(A){return yh.polygon(s,T,A)},u},een=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=d.height+s.padding,b=[{x:-v/2,y:0},{x:p,y:0},{x:p,y:-v},{x:-v/2,y:-v},{x:0,y:-v/2}];return r5(u,p,v,b).attr("style",s.style),s.width=p+v,s.height=v,s.intersect=function(T){return yh.polygon(s,b,T)},u},ten=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s),!0),p=d.width+s.padding,v=d.height+s.padding,b=[{x:-2*v/6,y:0},{x:p-v/6,y:0},{x:p+2*v/6,y:-v},{x:v/6,y:-v}],y=r5(u,p,v,b);return y.attr("style",s.style),Kh(s,y),s.intersect=function(T){return yh.polygon(s,b,T)},u},nen=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=d.height+s.padding,b=[{x:2*v/6,y:0},{x:p+v/6,y:0},{x:p-2*v/6,y:-v},{x:-v/6,y:-v}],y=r5(u,p,v,b);return y.attr("style",s.style),Kh(s,y),s.intersect=function(T){return yh.polygon(s,b,T)},u},ren=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=d.height+s.padding,b=[{x:-2*v/6,y:0},{x:p+2*v/6,y:0},{x:p-v/6,y:-v},{x:v/6,y:-v}],y=r5(u,p,v,b);return y.attr("style",s.style),Kh(s,y),s.intersect=function(T){return yh.polygon(s,b,T)},u},ien=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=d.height+s.padding,b=[{x:v/6,y:0},{x:p-v/6,y:0},{x:p+2*v/6,y:-v},{x:-2*v/6,y:-v}],y=r5(u,p,v,b);return y.attr("style",s.style),Kh(s,y),s.intersect=function(T){return yh.polygon(s,b,T)},u},sen=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=d.height+s.padding,b=[{x:0,y:0},{x:p+v/2,y:0},{x:p,y:-v/2},{x:p+v/2,y:-v},{x:0,y:-v}],y=r5(u,p,v,b);return y.attr("style",s.style),Kh(s,y),s.intersect=function(T){return yh.polygon(s,b,T)},u},aen=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=p/2,b=v/(2.5+p/50),y=d.height+b+s.padding,T="M 0,"+b+" a "+v+","+b+" 0,0,0 "+p+" 0 a "+v+","+b+" 0,0,0 "+-p+" 0 l 0,"+y+" a "+v+","+b+" 0,0,0 "+p+" 0 l 0,"+-y,_=u.attr("label-offset-y",b).insert("path",":first-child").attr("style",s.style).attr("d",T).attr("transform","translate("+-p/2+","+-(y/2+b)+")");return Kh(s,_),s.intersect=function(A){const P=yh.rect(s,A),R=P.x-s.x;if(v!=0&&(Math.abs(R)s.height/2-b)){let F=b*b*(1-R*R/(v*v));F!=0&&(F=Math.sqrt(F)),F=b-F,A.y-s.y>0&&(F=-F),P.y+=F}return P},u},oen=async(i,s)=>{const{shapeSvg:u,bbox:d,halfPadding:p}=await g1(i,s,"node "+s.classes+" "+s.class,!0),v=u.insert("rect",":first-child"),b=s.positioned?s.width:d.width+s.padding,y=s.positioned?s.height:d.height+s.padding,T=s.positioned?-b/2:-d.width/2-p,_=s.positioned?-y/2:-d.height/2-p;if(v.attr("class","basic label-container").attr("style",s.style).attr("rx",s.rx).attr("ry",s.ry).attr("x",T).attr("y",_).attr("width",b).attr("height",y),s.props){const A=new Set(Object.keys(s.props));s.props.borders&&(jme(v,s.props.borders,b,y),A.delete("borders")),A.forEach(P=>{Xe.warn(`Unknown node property ${P}`)})}return Kh(s,v),s.intersect=function(A){return yh.rect(s,A)},u},cen=async(i,s)=>{const{shapeSvg:u,bbox:d,halfPadding:p}=await g1(i,s,"node "+s.classes,!0),v=u.insert("rect",":first-child"),b=s.positioned?s.width:d.width+s.padding,y=s.positioned?s.height:d.height+s.padding,T=s.positioned?-b/2:-d.width/2-p,_=s.positioned?-y/2:-d.height/2-p;if(v.attr("class","basic cluster composite label-container").attr("style",s.style).attr("rx",s.rx).attr("ry",s.ry).attr("x",T).attr("y",_).attr("width",b).attr("height",y),s.props){const A=new Set(Object.keys(s.props));s.props.borders&&(jme(v,s.props.borders,b,y),A.delete("borders")),A.forEach(P=>{Xe.warn(`Unknown node property ${P}`)})}return Kh(s,v),s.intersect=function(A){return yh.rect(s,A)},u},uen=async(i,s)=>{const{shapeSvg:u}=await g1(i,s,"label",!0);Xe.trace("Classes = ",s.class);const d=u.insert("rect",":first-child"),p=0,v=0;if(d.attr("width",p).attr("height",v),u.attr("class","label edgeLabel"),s.props){const b=new Set(Object.keys(s.props));s.props.borders&&(jme(d,s.props.borders,p,v),b.delete("borders")),b.forEach(y=>{Xe.warn(`Unknown node property ${y}`)})}return Kh(s,d),s.intersect=function(b){return yh.rect(s,b)},u};function jme(i,s,u,d){const p=[],v=y=>{p.push(y,0)},b=y=>{p.push(0,y)};s.includes("t")?(Xe.debug("add top border"),v(u)):b(u),s.includes("r")?(Xe.debug("add right border"),v(d)):b(d),s.includes("b")?(Xe.debug("add bottom border"),v(u)):b(u),s.includes("l")?(Xe.debug("add left border"),v(d)):b(d),i.attr("stroke-dasharray",p.join(" "))}const len=(i,s)=>{let u;s.classes?u="node "+s.classes:u="node default";const d=i.insert("g").attr("class",u).attr("id",s.domId||s.id),p=d.insert("rect",":first-child"),v=d.insert("line"),b=d.insert("g").attr("class","label"),y=s.labelText.flat?s.labelText.flat():s.labelText;let T="";typeof y=="object"?T=y[0]:T=y,Xe.info("Label text abc79",T,y,typeof y=="object");const _=b.node().appendChild($2(T,s.labelStyle,!0,!0));let A={width:0,height:0};if(f1(qt().flowchart.htmlLabels)){const K=_.children[0],ee=Ir(_);A=K.getBoundingClientRect(),ee.attr("width",A.width),ee.attr("height",A.height)}Xe.info("Text 2",y);const P=y.slice(1,y.length);let R=_.getBBox();const F=b.node().appendChild($2(P.join?P.join("
"):P,s.labelStyle,!0,!0));if(f1(qt().flowchart.htmlLabels)){const K=F.children[0],ee=Ir(F);A=K.getBoundingClientRect(),ee.attr("width",A.width),ee.attr("height",A.height)}const j=s.padding/2;return Ir(F).attr("transform","translate( "+(A.width>R.width?0:(R.width-A.width)/2)+", "+(R.height+j+5)+")"),Ir(_).attr("transform","translate( "+(A.width{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.height+s.padding,v=d.width+p/4+s.padding,b=u.insert("rect",":first-child").attr("style",s.style).attr("rx",p/2).attr("ry",p/2).attr("x",-v/2).attr("y",-p/2).attr("width",v).attr("height",p);return Kh(s,b),s.intersect=function(y){return yh.rect(s,y)},u},fen=async(i,s)=>{const{shapeSvg:u,bbox:d,halfPadding:p}=await g1(i,s,dm(s,void 0),!0),v=u.insert("circle",":first-child");return v.attr("style",s.style).attr("rx",s.rx).attr("ry",s.ry).attr("r",d.width/2+p).attr("width",d.width+s.padding).attr("height",d.height+s.padding),Xe.info("Circle main"),Kh(s,v),s.intersect=function(b){return Xe.info("Circle intersect",s,d.width/2+p,b),yh.circle(s,d.width/2+p,b)},u},den=async(i,s)=>{const{shapeSvg:u,bbox:d,halfPadding:p}=await g1(i,s,dm(s,void 0),!0),v=5,b=u.insert("g",":first-child"),y=b.insert("circle"),T=b.insert("circle");return b.attr("class",s.class),y.attr("style",s.style).attr("rx",s.rx).attr("ry",s.ry).attr("r",d.width/2+p+v).attr("width",d.width+s.padding+v*2).attr("height",d.height+s.padding+v*2),T.attr("style",s.style).attr("rx",s.rx).attr("ry",s.ry).attr("r",d.width/2+p).attr("width",d.width+s.padding).attr("height",d.height+s.padding),Xe.info("DoubleCircle main"),Kh(s,y),s.intersect=function(_){return Xe.info("DoubleCircle intersect",s,d.width/2+p+v,_),yh.circle(s,d.width/2+p+v,_)},u},gen=async(i,s)=>{const{shapeSvg:u,bbox:d}=await g1(i,s,dm(s,void 0),!0),p=d.width+s.padding,v=d.height+s.padding,b=[{x:0,y:0},{x:p,y:0},{x:p,y:-v},{x:0,y:-v},{x:0,y:0},{x:-8,y:0},{x:p+8,y:0},{x:p+8,y:-v},{x:-8,y:-v},{x:-8,y:0}],y=r5(u,p,v,b);return y.attr("style",s.style),Kh(s,y),s.intersect=function(T){return yh.polygon(s,b,T)},u},pen=(i,s)=>{const u=i.insert("g").attr("class","node default").attr("id",s.domId||s.id),d=u.insert("circle",":first-child");return d.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),Kh(s,d),s.intersect=function(p){return yh.circle(s,7,p)},u},TUe=(i,s,u)=>{const d=i.insert("g").attr("class","node default").attr("id",s.domId||s.id);let p=70,v=10;u==="LR"&&(p=10,v=70);const b=d.append("rect").attr("x",-1*p/2).attr("y",-1*v/2).attr("width",p).attr("height",v).attr("class","fork-join");return Kh(s,b),s.height=s.height+s.padding/2,s.width=s.width+s.padding/2,s.intersect=function(y){return yh.rect(s,y)},d},CUe={rhombus:EUe,composite:cen,question:EUe,rect:oen,labelRect:uen,rectWithTitle:len,choice:QZt,circle:fen,doublecircle:den,stadium:hen,hexagon:JZt,block_arrow:ZZt,rect_left_inv_arrow:een,lean_right:ten,lean_left:nen,trapezoid:ren,inv_trapezoid:ien,rect_right_inv_arrow:sen,cylinder:aen,start:pen,end:(i,s)=>{const u=i.insert("g").attr("class","node default").attr("id",s.domId||s.id),d=u.insert("circle",":first-child"),p=u.insert("circle",":first-child");return p.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),d.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),Kh(s,p),s.intersect=function(v){return yh.circle(s,7,v)},u},note:WZt,subroutine:gen,fork:TUe,join:TUe,class_box:(i,s)=>{const u=s.padding/2,d=4,p=8;let v;s.classes?v="node "+s.classes:v="node default";const b=i.insert("g").attr("class",v).attr("id",s.domId||s.id),y=b.insert("rect",":first-child"),T=b.insert("line"),_=b.insert("line");let A=0,P=d;const R=b.insert("g").attr("class","label");let F=0;const j=s.classData.annotations&&s.classData.annotations[0],K=s.classData.annotations[0]?"«"+s.classData.annotations[0]+"»":"",ee=R.node().appendChild($2(K,s.labelStyle,!0,!0));let ie=ee.getBBox();if(f1(qt().flowchart.htmlLabels)){const de=ee.children[0],X=Ir(ee);ie=de.getBoundingClientRect(),X.attr("width",ie.width),X.attr("height",ie.height)}s.classData.annotations[0]&&(P+=ie.height+d,A+=ie.width);let oe=s.classData.label;s.classData.type!==void 0&&s.classData.type!==""&&(qt().flowchart.htmlLabels?oe+="<"+s.classData.type+">":oe+="<"+s.classData.type+">");const pe=R.node().appendChild($2(oe,s.labelStyle,!0,!0));Ir(pe).attr("class","classTitle");let be=pe.getBBox();if(f1(qt().flowchart.htmlLabels)){const de=pe.children[0],X=Ir(pe);be=de.getBoundingClientRect(),X.attr("width",be.width),X.attr("height",be.height)}P+=be.height+d,be.width>A&&(A=be.width);const ae=[];s.classData.members.forEach(de=>{const X=de.getDisplayDetails();let ge=X.displayText;qt().flowchart.htmlLabels&&(ge=ge.replace(//g,">"));const W=R.node().appendChild($2(ge,X.cssStyle?X.cssStyle:s.labelStyle,!0,!0));let xe=W.getBBox();if(f1(qt().flowchart.htmlLabels)){const U=W.children[0],Fe=Ir(W);xe=U.getBoundingClientRect(),Fe.attr("width",xe.width),Fe.attr("height",xe.height)}xe.width>A&&(A=xe.width),P+=xe.height+d,ae.push(W)}),P+=p;const ne=[];if(s.classData.methods.forEach(de=>{const X=de.getDisplayDetails();let ge=X.displayText;qt().flowchart.htmlLabels&&(ge=ge.replace(//g,">"));const W=R.node().appendChild($2(ge,X.cssStyle?X.cssStyle:s.labelStyle,!0,!0));let xe=W.getBBox();if(f1(qt().flowchart.htmlLabels)){const U=W.children[0],Fe=Ir(W);xe=U.getBoundingClientRect(),Fe.attr("width",xe.width),Fe.attr("height",xe.height)}xe.width>A&&(A=xe.width),P+=xe.height+d,ne.push(W)}),P+=p,j){let de=(A-ie.width)/2;Ir(ee).attr("transform","translate( "+(-1*A/2+de)+", "+-1*P/2+")"),F=ie.height+d}let se=(A-be.width)/2;return Ir(pe).attr("transform","translate( "+(-1*A/2+se)+", "+(-1*P/2+F)+")"),F+=be.height+d,T.attr("class","divider").attr("x1",-A/2-u).attr("x2",A/2+u).attr("y1",-P/2-u+p+F).attr("y2",-P/2-u+p+F),F+=p,ae.forEach(de=>{Ir(de).attr("transform","translate( "+-A/2+", "+(-1*P/2+F+p/2)+")");const X=de==null?void 0:de.getBBox();F+=((X==null?void 0:X.height)??0)+d}),F+=p,_.attr("class","divider").attr("x1",-A/2-u).attr("x2",A/2+u).attr("y1",-P/2-u+p+F).attr("y2",-P/2-u+p+F),F+=p,ne.forEach(de=>{Ir(de).attr("transform","translate( "+-A/2+", "+(-1*P/2+F)+")");const X=de==null?void 0:de.getBBox();F+=((X==null?void 0:X.height)??0)+d}),y.attr("style",s.style).attr("class","outer title-state").attr("x",-A/2-u).attr("y",-(P/2)-u).attr("width",A+s.padding).attr("height",P+s.padding),Kh(s,y),s.intersect=function(de){return yh.rect(s,de)},b}};let VD={};const tJ=async(i,s,u)=>{let d,p;if(s.link){let v;qt().securityLevel==="sandbox"?v="_top":s.linkTarget&&(v=s.linkTarget||"_blank"),d=i.insert("svg:a").attr("xlink:href",s.link).attr("target",v),p=await CUe[s.shape](d,s,u)}else p=await CUe[s.shape](i,s,u),d=p;return s.tooltip&&p.attr("title",s.tooltip),s.class&&p.attr("class","node default "+s.class),d.attr("data-node","true"),d.attr("data-id",s.id),VD[s.id]=d,s.haveCallback&&VD[s.id].attr("class",VD[s.id].attr("class")+" clickable"),d},ben=(i,s)=>{VD[s.id]=i},men=()=>{VD={}},$me=i=>{const s=VD[i.id];Xe.trace("Transforming node",i.diff,i,"translate("+(i.x-i.width/2-5)+", "+i.width/2+")");const u=8,d=i.diff||0;return i.clusterNode?s.attr("transform","translate("+(i.x+d-i.width/2)+", "+(i.y-i.height/2-u)+")"):s.attr("transform","translate("+i.x+", "+i.y+")"),d},nJ=({flowchart:i})=>{var p,v;const s=((p=i==null?void 0:i.subGraphTitleMargin)==null?void 0:p.top)??0,u=((v=i==null?void 0:i.subGraphTitleMargin)==null?void 0:v.bottom)??0,d=s+u;return{subGraphTitleTopMargin:s,subGraphTitleBottomMargin:u,subGraphTitleTotalMargin:d}},ven={rect:(i,s)=>{Xe.info("Creating subgraph rect for ",s.id,s);const u=qt(),d=i.insert("g").attr("class","cluster"+(s.class?" "+s.class:"")).attr("id",s.id),p=d.insert("rect",":first-child"),v=f1(u.flowchart.htmlLabels),b=d.insert("g").attr("class","cluster-label"),y=s.labelType==="markdown"?JQ(b,s.labelText,{style:s.labelStyle,useHtmlLabels:v}):b.node().appendChild($2(s.labelText,s.labelStyle,void 0,!0));let T=y.getBBox();if(f1(u.flowchart.htmlLabels)){const j=y.children[0],K=Ir(y);T=j.getBoundingClientRect(),K.attr("width",T.width),K.attr("height",T.height)}const _=0*s.padding,A=_/2,P=s.width<=T.width+_?T.width+_:s.width;s.width<=T.width+_?s.diff=(T.width-s.width)/2-s.padding/2:s.diff=-s.padding/2,Xe.trace("Data ",s,JSON.stringify(s)),p.attr("style",s.style).attr("rx",s.rx).attr("ry",s.ry).attr("x",s.x-P/2).attr("y",s.y-s.height/2-A).attr("width",P).attr("height",s.height+_);const{subGraphTitleTopMargin:R}=nJ(u);v?b.attr("transform",`translate(${s.x-T.width/2}, ${s.y-s.height/2+R})`):b.attr("transform",`translate(${s.x}, ${s.y-s.height/2+R})`);const F=p.node().getBBox();return s.width=F.width,s.height=F.height,s.intersect=function(j){return DR(s,j)},d},roundedWithTitle:(i,s)=>{const u=qt(),d=i.insert("g").attr("class",s.classes).attr("id",s.id),p=d.insert("rect",":first-child"),v=d.insert("g").attr("class","cluster-label"),b=d.append("rect"),y=v.node().appendChild($2(s.labelText,s.labelStyle,void 0,!0));let T=y.getBBox();if(f1(u.flowchart.htmlLabels)){const j=y.children[0],K=Ir(y);T=j.getBoundingClientRect(),K.attr("width",T.width),K.attr("height",T.height)}T=y.getBBox();const _=0*s.padding,A=_/2,P=s.width<=T.width+s.padding?T.width+s.padding:s.width;s.width<=T.width+s.padding?s.diff=(T.width+s.padding*0-s.width)/2:s.diff=-s.padding/2,p.attr("class","outer").attr("x",s.x-P/2-A).attr("y",s.y-s.height/2-A).attr("width",P+_).attr("height",s.height+_),b.attr("class","inner").attr("x",s.x-P/2-A).attr("y",s.y-s.height/2-A+T.height-1).attr("width",P+_).attr("height",s.height+_-T.height-3);const{subGraphTitleTopMargin:R}=nJ(u);v.attr("transform",`translate(${s.x-T.width/2}, ${s.y-s.height/2-s.padding/3+(f1(u.flowchart.htmlLabels)?5:3)+R})`);const F=p.node().getBBox();return s.height=F.height,s.intersect=function(j){return DR(s,j)},d},noteGroup:(i,s)=>{const u=i.insert("g").attr("class","note-cluster").attr("id",s.id),d=u.insert("rect",":first-child"),p=0*s.padding,v=p/2;d.attr("rx",s.rx).attr("ry",s.ry).attr("x",s.x-s.width/2-v).attr("y",s.y-s.height/2-v).attr("width",s.width+p).attr("height",s.height+p).attr("fill","none");const b=d.node().getBBox();return s.width=b.width,s.height=b.height,s.intersect=function(y){return DR(s,y)},u},divider:(i,s)=>{const u=i.insert("g").attr("class",s.classes).attr("id",s.id),d=u.insert("rect",":first-child"),p=0*s.padding,v=p/2;d.attr("class","divider").attr("x",s.x-s.width/2-v).attr("y",s.y-s.height/2).attr("width",s.width+p).attr("height",s.height+p);const b=d.node().getBBox();return s.width=b.width,s.height=b.height,s.diff=-s.padding/2,s.intersect=function(y){return DR(s,y)},u}};let SUe={};const wen=(i,s)=>{Xe.trace("Inserting cluster");const u=s.shape||"rect";SUe[s.id]=ven[u](i,s)},yen=()=>{SUe={}},P9={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:5.3};function rJ(i,s){if(i===void 0||s===void 0)return{angle:0,deltaX:0,deltaY:0};i=iJ(i),s=iJ(s);const[u,d]=[i.x,i.y],[p,v]=[s.x,s.y],b=p-u,y=v-d;return{angle:Math.atan(y/b),deltaX:b,deltaY:y}}const iJ=i=>Array.isArray(i)?{x:i[0],y:i[1]}:i,_Ue=i=>({x:function(s,u,d){let p=0;if(u===0&&Object.hasOwn(P9,i.arrowTypeStart)){const{angle:v,deltaX:b}=rJ(d[0],d[1]);p=P9[i.arrowTypeStart]*Math.cos(v)*(b>=0?1:-1)}else if(u===d.length-1&&Object.hasOwn(P9,i.arrowTypeEnd)){const{angle:v,deltaX:b}=rJ(d[d.length-1],d[d.length-2]);p=P9[i.arrowTypeEnd]*Math.cos(v)*(b>=0?1:-1)}return iJ(s).x+p},y:function(s,u,d){let p=0;if(u===0&&Object.hasOwn(P9,i.arrowTypeStart)){const{angle:v,deltaY:b}=rJ(d[0],d[1]);p=P9[i.arrowTypeStart]*Math.abs(Math.sin(v))*(b>=0?1:-1)}else if(u===d.length-1&&Object.hasOwn(P9,i.arrowTypeEnd)){const{angle:v,deltaY:b}=rJ(d[d.length-1],d[d.length-2]);p=P9[i.arrowTypeEnd]*Math.abs(Math.sin(v))*(b>=0?1:-1)}return iJ(s).y+p}}),AUe=(i,s,u,d,p)=>{s.arrowTypeStart&&LUe(i,"start",s.arrowTypeStart,u,d,p),s.arrowTypeEnd&&LUe(i,"end",s.arrowTypeEnd,u,d,p)},xen={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},LUe=(i,s,u,d,p,v)=>{const b=xen[u];if(!b){Xe.warn(`Unknown arrow type: ${u}`);return}const y=s==="start"?"Start":"End";i.attr(`marker-${s}`,`url(${d}#${p}_${v}-${b}${y})`)};let sJ={},Vd={};const ken=()=>{sJ={},Vd={}},zme=(i,s)=>{const u=f1(qt().flowchart.htmlLabels),d=s.labelType==="markdown"?JQ(i,s.label,{style:s.labelStyle,useHtmlLabels:u,addSvgBackground:!0}):$2(s.label,s.labelStyle),p=i.insert("g").attr("class","edgeLabel"),v=p.insert("g").attr("class","label");v.node().appendChild(d);let b=d.getBBox();if(u){const T=d.children[0],_=Ir(d);b=T.getBoundingClientRect(),_.attr("width",b.width),_.attr("height",b.height)}v.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"),sJ[s.id]=p,s.width=b.width,s.height=b.height;let y;if(s.startLabelLeft){const T=$2(s.startLabelLeft,s.labelStyle),_=i.insert("g").attr("class","edgeTerminals"),A=_.insert("g").attr("class","inner");y=A.node().appendChild(T);const P=T.getBBox();A.attr("transform","translate("+-P.width/2+", "+-P.height/2+")"),Vd[s.id]||(Vd[s.id]={}),Vd[s.id].startLeft=_,aJ(y,s.startLabelLeft)}if(s.startLabelRight){const T=$2(s.startLabelRight,s.labelStyle),_=i.insert("g").attr("class","edgeTerminals"),A=_.insert("g").attr("class","inner");y=_.node().appendChild(T),A.node().appendChild(T);const P=T.getBBox();A.attr("transform","translate("+-P.width/2+", "+-P.height/2+")"),Vd[s.id]||(Vd[s.id]={}),Vd[s.id].startRight=_,aJ(y,s.startLabelRight)}if(s.endLabelLeft){const T=$2(s.endLabelLeft,s.labelStyle),_=i.insert("g").attr("class","edgeTerminals"),A=_.insert("g").attr("class","inner");y=A.node().appendChild(T);const P=T.getBBox();A.attr("transform","translate("+-P.width/2+", "+-P.height/2+")"),_.node().appendChild(T),Vd[s.id]||(Vd[s.id]={}),Vd[s.id].endLeft=_,aJ(y,s.endLabelLeft)}if(s.endLabelRight){const T=$2(s.endLabelRight,s.labelStyle),_=i.insert("g").attr("class","edgeTerminals"),A=_.insert("g").attr("class","inner");y=A.node().appendChild(T);const P=T.getBBox();A.attr("transform","translate("+-P.width/2+", "+-P.height/2+")"),_.node().appendChild(T),Vd[s.id]||(Vd[s.id]={}),Vd[s.id].endRight=_,aJ(y,s.endLabelRight)}return d};function aJ(i,s){qt().flowchart.htmlLabels&&i&&(i.style.width=s.length*9+"px",i.style.height="12px")}const MUe=(i,s)=>{Xe.debug("Moving label abc88 ",i.id,i.label,sJ[i.id],s);let u=s.updatedPath?s.updatedPath:s.originalPath;const d=qt(),{subGraphTitleTotalMargin:p}=nJ(d);if(i.label){const v=sJ[i.id];let b=i.x,y=i.y;if(u){const T=Ao.calcLabelPosition(u);Xe.debug("Moving label "+i.label+" from (",b,",",y,") to (",T.x,",",T.y,") abc88"),s.updatedPath&&(b=T.x,y=T.y)}v.attr("transform",`translate(${b}, ${y+p/2})`)}if(i.startLabelLeft){const v=Vd[i.id].startLeft;let b=i.x,y=i.y;if(u){const T=Ao.calcTerminalLabelPosition(i.arrowTypeStart?10:0,"start_left",u);b=T.x,y=T.y}v.attr("transform",`translate(${b}, ${y})`)}if(i.startLabelRight){const v=Vd[i.id].startRight;let b=i.x,y=i.y;if(u){const T=Ao.calcTerminalLabelPosition(i.arrowTypeStart?10:0,"start_right",u);b=T.x,y=T.y}v.attr("transform",`translate(${b}, ${y})`)}if(i.endLabelLeft){const v=Vd[i.id].endLeft;let b=i.x,y=i.y;if(u){const T=Ao.calcTerminalLabelPosition(i.arrowTypeEnd?10:0,"end_left",u);b=T.x,y=T.y}v.attr("transform",`translate(${b}, ${y})`)}if(i.endLabelRight){const v=Vd[i.id].endRight;let b=i.x,y=i.y;if(u){const T=Ao.calcTerminalLabelPosition(i.arrowTypeEnd?10:0,"end_right",u);b=T.x,y=T.y}v.attr("transform",`translate(${b}, ${y})`)}},Een=(i,s)=>{const u=i.x,d=i.y,p=Math.abs(s.x-u),v=Math.abs(s.y-d),b=i.width/2,y=i.height/2;return p>=b||v>=y},Ten=(i,s,u)=>{Xe.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(s)} + insidePoint : ${JSON.stringify(u)} + node : x:${i.x} y:${i.y} w:${i.width} h:${i.height}`);const d=i.x,p=i.y,v=Math.abs(d-u.x),b=i.width/2;let y=u.xMath.abs(d-s.x)*T){let P=u.y{Xe.debug("abc88 cutPathAtIntersect",i,s);let u=[],d=i[0],p=!1;return i.forEach(v=>{if(!Een(s,v)&&!p){const b=Ten(s,d,v);let y=!1;u.forEach(T=>{y=y||T.x===b.x&&T.y===b.y}),u.some(T=>T.x===b.x&&T.y===b.y)||u.push(b),p=!0}else d=v,p||u.push(v)}),u},IUe=function(i,s,u,d,p,v,b){let y=u.points;Xe.debug("abc88 InsertEdge: edge=",u,"e=",s);let T=!1;const _=v.node(s.v);var A=v.node(s.w);A!=null&&A.intersect&&(_!=null&&_.intersect)&&(y=y.slice(1,u.points.length-1),y.unshift(_.intersect(y[0])),y.push(A.intersect(y[y.length-1]))),u.toCluster&&(Xe.debug("to cluster abc88",d[u.toCluster]),y=DUe(u.points,d[u.toCluster].node),T=!0),u.fromCluster&&(Xe.debug("from cluster abc88",d[u.fromCluster]),y=DUe(y.reverse(),d[u.fromCluster].node).reverse(),T=!0);const P=y.filter(be=>!Number.isNaN(be.y));let R=FF;u.curve&&(p==="graph"||p==="flowchart")&&(R=u.curve);const{x:F,y:j}=_Ue(u),K=k7().x(F).y(j).curve(R);let ee;switch(u.thickness){case"normal":ee="edge-thickness-normal";break;case"thick":ee="edge-thickness-thick";break;case"invisible":ee="edge-thickness-thick";break;default:ee=""}switch(u.pattern){case"solid":ee+=" edge-pattern-solid";break;case"dotted":ee+=" edge-pattern-dotted";break;case"dashed":ee+=" edge-pattern-dashed";break}const ie=i.append("path").attr("d",K(P)).attr("id",u.id).attr("class"," "+ee+(u.classes?" "+u.classes:"")).attr("style",u.style);let oe="";(qt().flowchart.arrowMarkerAbsolute||qt().state.arrowMarkerAbsolute)&&(oe=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,oe=oe.replace(/\(/g,"\\("),oe=oe.replace(/\)/g,"\\)")),AUe(ie,u,oe,b,p);let pe={};return T&&(pe.updatedPath=y),pe.originalPath=u.points,pe},OUe=async(i,s,u,d,p,v)=>{Xe.info("Graph in recursive render: XXX",q7(s),p);const b=s.graph().rankdir;Xe.trace("Dir in recursive render - dir:",b);const y=i.insert("g").attr("class","root");s.nodes()?Xe.info("Recursive render XXX",s.nodes()):Xe.info("No nodes found for",s),s.edges().length>0&&Xe.trace("Recursive edges",s.edge(s.edges()[0]));const T=y.insert("g").attr("class","clusters"),_=y.insert("g").attr("class","edgePaths"),A=y.insert("g").attr("class","edgeLabels"),P=y.insert("g").attr("class","nodes");await Promise.all(s.nodes().map(async function(j){const K=s.node(j);if(p!==void 0){const ee=JSON.parse(JSON.stringify(p.clusterData));Xe.info("Setting data for cluster XXX (",j,") ",ee,p),s.setNode(p.id,ee),s.parent(j)||(Xe.trace("Setting parent",j,p.id),s.setParent(j,p.id,ee))}if(Xe.info("(Insert) Node XXX"+j+": "+JSON.stringify(s.node(j))),K&&K.clusterNode){Xe.info("Cluster identified",j,K.width,s.node(j));const ee=await OUe(P,K.graph,u,d,s.node(j),v),ie=ee.elem;Kh(K,ie),K.diff=ee.diff||0,Xe.info("Node bounds (abc123)",j,K,K.width,K.x,K.y),ben(ie,K),Xe.warn("Recursive render complete ",ie,K)}else s.children(j).length>0?(Xe.info("Cluster - the non recursive path XXX",j,K.id,K,s),Xe.info(MR(K.id,s)),Mo[K.id]={id:MR(K.id,s),node:K}):(Xe.info("Node - the non recursive path",j,K.id,K),await tJ(P,s.node(j),b))})),s.edges().forEach(function(j){const K=s.edge(j.v,j.w,j.name);Xe.info("Edge "+j.v+" -> "+j.w+": "+JSON.stringify(j)),Xe.info("Edge "+j.v+" -> "+j.w+": ",j," ",JSON.stringify(s.edge(j))),Xe.info("Fix",Mo,"ids:",j.v,j.w,"Translating: ",Mo[j.v],Mo[j.w]),zme(A,K)}),s.edges().forEach(function(j){Xe.info("Edge "+j.v+" -> "+j.w+": "+JSON.stringify(j))}),Xe.info("#############################################"),Xe.info("### Layout ###"),Xe.info("#############################################"),Xe.info(s),qD(s),Xe.info("Graph after layout:",q7(s));let R=0;const{subGraphTitleTotalMargin:F}=nJ(v);return HZt(s).forEach(function(j){const K=s.node(j);Xe.info("Position "+j+": "+JSON.stringify(s.node(j))),Xe.info("Position "+j+": ("+K.x,","+K.y,") width: ",K.width," height: ",K.height),K&&K.clusterNode?(K.y+=F,$me(K)):s.children(j).length>0?(K.height+=F,wen(T,K),Mo[K.id].node=K):(K.y+=F/2,$me(K))}),s.edges().forEach(function(j){const K=s.edge(j);Xe.info("Edge "+j.v+" -> "+j.w+": "+JSON.stringify(K),K),K.points.forEach(ie=>ie.y+=F/2);const ee=IUe(_,j,K,Mo,u,s,d);MUe(K,ee)}),s.nodes().forEach(function(j){const K=s.node(j);Xe.info(j,K.type,K.diff),K.type==="group"&&(R=K.diff)}),{elem:y,diff:R}},qme=async(i,s,u,d,p)=>{Sme(i,u,d,p),men(),ken(),yen(),$Zt(),Xe.warn("Graph at first:",JSON.stringify(q7(s))),qZt(s),Xe.warn("Graph after:",JSON.stringify(q7(s)));const v=qt();await OUe(i,s,d,p,void 0,v)},NUe={},Cen=function(i){const s=Object.keys(i);for(const u of s)NUe[u]=i[u]},PUe=async function(i,s,u,d,p,v){const b=d.select(`[id="${u}"]`),y=Object.keys(i);for(const T of y){const _=i[T];let A="default";_.classes.length>0&&(A=_.classes.join(" ")),A=A+" flowchart-label";const P=om(_.styles);let R=_.text!==void 0?_.text:_.id,F;if(Xe.info("vertex",_,_.labelType),_.labelType==="markdown")Xe.info("vertex",_,_.labelType);else if(f1(qt().flowchart.htmlLabels))F=vme(b,{label:R}).node(),F.parentNode.removeChild(F);else{const ie=p.createElementNS("http://www.w3.org/2000/svg","text");ie.setAttribute("style",P.labelStyle.replace("color:","fill:"));const oe=R.split(ci.lineBreakRegex);for(const pe of oe){const be=p.createElementNS("http://www.w3.org/2000/svg","tspan");be.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),be.setAttribute("dy","1em"),be.setAttribute("x","1"),be.textContent=pe,ie.appendChild(be)}F=ie}let j=0,K="";switch(_.type){case"round":j=5,K="rect";break;case"square":K="rect";break;case"diamond":K="question";break;case"hexagon":K="hexagon";break;case"odd":K="rect_left_inv_arrow";break;case"lean_right":K="lean_right";break;case"lean_left":K="lean_left";break;case"trapezoid":K="trapezoid";break;case"inv_trapezoid":K="inv_trapezoid";break;case"odd_right":K="rect_left_inv_arrow";break;case"circle":K="circle";break;case"ellipse":K="ellipse";break;case"stadium":K="stadium";break;case"subroutine":K="subroutine";break;case"cylinder":K="cylinder";break;case"group":K="rect";break;case"doublecircle":K="doublecircle";break;default:K="rect"}const ee=await CC(R,qt());s.setNode(_.id,{labelStyle:P.labelStyle,shape:K,labelText:ee,labelType:_.labelType,rx:j,ry:j,class:A,style:P.style,id:_.id,link:_.link,linkTarget:_.linkTarget,tooltip:v.db.getTooltip(_.id)||"",domId:v.db.lookUpDomId(_.id),haveCallback:_.haveCallback,width:_.type==="group"?500:void 0,dir:_.dir,type:_.type,props:_.props,padding:qt().flowchart.padding}),Xe.info("setNode",{labelStyle:P.labelStyle,labelType:_.labelType,shape:K,labelText:ee,rx:j,ry:j,class:A,style:P.style,id:_.id,domId:v.db.lookUpDomId(_.id),width:_.type==="group"?500:void 0,type:_.type,dir:_.dir,props:_.props,padding:qt().flowchart.padding})}},BUe=async function(i,s,u){Xe.info("abc78 edges = ",i);let d=0,p={},v,b;if(i.defaultStyle!==void 0){const y=om(i.defaultStyle);v=y.style,b=y.labelStyle}for(const y of i){d++;const T="L-"+y.start+"-"+y.end;p[T]===void 0?(p[T]=0,Xe.info("abc78 new entry",T,p[T])):(p[T]++,Xe.info("abc78 new entry",T,p[T]));let _=T+"-"+p[T];Xe.info("abc78 new link id to be used is",T,_,p[T]);const A="LS-"+y.start,P="LE-"+y.end,R={style:"",labelStyle:""};switch(R.minlen=y.length||1,y.type==="arrow_open"?R.arrowhead="none":R.arrowhead="normal",R.arrowTypeStart="arrow_open",R.arrowTypeEnd="arrow_open",y.type){case"double_arrow_cross":R.arrowTypeStart="arrow_cross";case"arrow_cross":R.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":R.arrowTypeStart="arrow_point";case"arrow_point":R.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":R.arrowTypeStart="arrow_circle";case"arrow_circle":R.arrowTypeEnd="arrow_circle";break}let F="",j="";switch(y.stroke){case"normal":F="fill:none;",v!==void 0&&(F=v),b!==void 0&&(j=b),R.thickness="normal",R.pattern="solid";break;case"dotted":R.thickness="normal",R.pattern="dotted",R.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":R.thickness="thick",R.pattern="solid",R.style="stroke-width: 3.5px;fill:none;";break;case"invisible":R.thickness="invisible",R.pattern="solid",R.style="stroke-width: 0;fill:none;";break}if(y.style!==void 0){const K=om(y.style);F=K.style,j=K.labelStyle}R.style=R.style+=F,R.labelStyle=R.labelStyle+=j,y.interpolate!==void 0?R.curve=Ov(y.interpolate,kp):i.defaultInterpolate!==void 0?R.curve=Ov(i.defaultInterpolate,kp):R.curve=Ov(NUe.curve,kp),y.text===void 0?y.style!==void 0&&(R.arrowheadStyle="fill: #333"):(R.arrowheadStyle="fill: #333",R.labelpos="c"),R.labelType=y.labelType,R.label=await CC(y.text.replace(ci.lineBreakRegex,` +`),qt()),y.style===void 0&&(R.style=R.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),R.labelStyle=R.labelStyle.replace("color:","fill:"),R.id=_,R.classes="flowchart-link "+A+" "+P,s.setEdge(y.start,y.end,R,d)}},Hme={setConf:Cen,addVertices:PUe,addEdges:BUe,getClasses:function(i,s){return s.db.getClasses()},draw:async function(i,s,u,d){Xe.info("Drawing flowchart");let p=d.db.getDirection();p===void 0&&(p="TD");const{securityLevel:v,flowchart:b}=qt(),y=b.nodeSpacing||50,T=b.rankSpacing||50;let _;v==="sandbox"&&(_=Ir("#i"+s));const A=Ir(v==="sandbox"?_.nodes()[0].contentDocument.body:"body"),P=v==="sandbox"?_.nodes()[0].contentDocument:document,R=new B0({multigraph:!0,compound:!0}).setGraph({rankdir:p,nodesep:y,ranksep:T,marginx:0,marginy:0}).setDefaultEdgeLabel(function(){return{}});let F;const j=d.db.getSubGraphs();Xe.info("Subgraphs - ",j);for(let ae=j.length-1;ae>=0;ae--)F=j[ae],Xe.info("Subgraph - ",F),d.db.addVertex(F.id,{text:F.title,type:F.labelType},"group",void 0,F.classes,F.dir);const K=d.db.getVertices(),ee=d.db.getEdges();Xe.info("Edges",ee);let ie=0;for(ie=j.length-1;ie>=0;ie--){F=j[ie],_Be("cluster").append("text");for(let ae=0;ae{const u=ARe,d=u(i,"r"),p=u(i,"g"),v=u(i,"b");return SC(d,p,v,s)},FUe=i=>`.label { + font-family: ${i.fontFamily}; + color: ${i.nodeTextColor||i.textColor}; + } + .cluster-label text { + fill: ${i.titleColor}; + } + .cluster-label span,p { + color: ${i.titleColor}; + } + + .label text,span,p { + fill: ${i.nodeTextColor||i.textColor}; + color: ${i.nodeTextColor||i.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${i.mainBkg}; + stroke: ${i.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 .katex path { + fill: #000; + stroke: #000; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${i.arrowheadColor}; + } + + .edgePath .path { + stroke: ${i.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${i.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${i.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${i.edgeLabelBackground}; + fill: ${i.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${Sen(i.edgeLabelBackground,.5)}; + // background-color: + } + + .cluster rect { + fill: ${i.clusterBkg}; + stroke: ${i.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${i.titleColor}; + } + + .cluster span,p { + color: ${i.titleColor}; + } + /* .cluster div { + color: ${i.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${i.fontFamily}; + font-size: 12px; + background: ${i.tertiaryColor}; + border: 1px solid ${i.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.textColor}; + } +`,_en=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:Gbe,db:HC,renderer:Hme,styles:FUe,init:i=>{i.flowchart||(i.flowchart={}),i.flowchart.arrowMarkerAbsolute=i.arrowMarkerAbsolute,_Qt.setConf(i.flowchart),HC.clear(),HC.setGen("gen-1")}}},Symbol.toStringTag,{value:"Module"})),Aen=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:Gbe,db:HC,renderer:Hme,styles:FUe,init:i=>{i.flowchart||(i.flowchart={}),i.flowchart.arrowMarkerAbsolute=i.arrowMarkerAbsolute,_jt({flowchart:{arrowMarkerAbsolute:i.arrowMarkerAbsolute}}),Hme.setConf(i.flowchart),HC.clear(),HC.setGen("gen-2")}}},Symbol.toStringTag,{value:"Module"}));var Vme=function(){var i=function(de,X,ge,W){for(ge=ge||{},W=de.length;W--;ge[de[W]]=X);return ge},s=[6,8,10,20,22,24,26,27,28],u=[1,10],d=[1,11],p=[1,12],v=[1,13],b=[1,14],y=[1,15],T=[1,21],_=[1,22],A=[1,23],P=[1,24],R=[1,25],F=[6,8,10,13,15,18,19,20,22,24,26,27,28,41,42,43,44,45],j=[1,34],K=[27,28,46,47],ee=[41,42,43,44,45],ie=[17,34],oe=[1,54],pe=[1,53],be=[17,34,36,38],ae={trace:function(){},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,":":13,role:14,BLOCK_START:15,attributes:16,BLOCK_STOP:17,SQS:18,SQE:19,title:20,title_value:21,acc_title:22,acc_title_value:23,acc_descr:24,acc_descr_value:25,acc_descr_multiline_value:26,ALPHANUM:27,ENTITY_NAME:28,attribute:29,attributeType:30,attributeName:31,attributeKeyTypeList:32,attributeComment:33,ATTRIBUTE_WORD:34,attributeKeyType:35,COMMA:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,MD_PARENT:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:":",15:"BLOCK_START",17:"BLOCK_STOP",18:"SQS",19:"SQE",20:"title",21:"title_value",22:"acc_title",23:"acc_title_value",24:"acc_descr",25:"acc_descr_value",26:"acc_descr_multiline_value",27:"ALPHANUM",28:"ENTITY_NAME",34:"ATTRIBUTE_WORD",36:"COMMA",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"MD_PARENT",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,4],[9,3],[9,1],[9,7],[9,6],[9,4],[9,2],[9,2],[9,2],[9,1],[11,1],[11,1],[16,1],[16,2],[29,2],[29,3],[29,3],[29,4],[30,1],[31,1],[32,1],[32,3],[35,1],[33,1],[12,3],[39,1],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[14,1],[14,1],[14,1]],performAction:function(X,ge,W,xe,U,Fe,Pe){var je=Fe.length-1;switch(U){case 1:break;case 2:this.$=[];break;case 3:Fe[je-1].push(Fe[je]),this.$=Fe[je-1];break;case 4:case 5:this.$=Fe[je];break;case 6:case 7:this.$=[];break;case 8:xe.addEntity(Fe[je-4]),xe.addEntity(Fe[je-2]),xe.addRelationship(Fe[je-4],Fe[je],Fe[je-2],Fe[je-3]);break;case 9:xe.addEntity(Fe[je-3]),xe.addAttributes(Fe[je-3],Fe[je-1]);break;case 10:xe.addEntity(Fe[je-2]);break;case 11:xe.addEntity(Fe[je]);break;case 12:xe.addEntity(Fe[je-6],Fe[je-4]),xe.addAttributes(Fe[je-6],Fe[je-1]);break;case 13:xe.addEntity(Fe[je-5],Fe[je-3]);break;case 14:xe.addEntity(Fe[je-3],Fe[je-1]);break;case 15:case 16:this.$=Fe[je].trim(),xe.setAccTitle(this.$);break;case 17:case 18:this.$=Fe[je].trim(),xe.setAccDescription(this.$);break;case 19:case 43:this.$=Fe[je];break;case 20:case 41:case 42:this.$=Fe[je].replace(/"/g,"");break;case 21:case 29:this.$=[Fe[je]];break;case 22:Fe[je].push(Fe[je-1]),this.$=Fe[je];break;case 23:this.$={attributeType:Fe[je-1],attributeName:Fe[je]};break;case 24:this.$={attributeType:Fe[je-2],attributeName:Fe[je-1],attributeKeyTypeList:Fe[je]};break;case 25:this.$={attributeType:Fe[je-2],attributeName:Fe[je-1],attributeComment:Fe[je]};break;case 26:this.$={attributeType:Fe[je-3],attributeName:Fe[je-2],attributeKeyTypeList:Fe[je-1],attributeComment:Fe[je]};break;case 27:case 28:case 31:this.$=Fe[je];break;case 30:Fe[je-2].push(Fe[je]),this.$=Fe[je-2];break;case 32:this.$=Fe[je].replace(/"/g,"");break;case 33:this.$={cardA:Fe[je],relType:Fe[je-1],cardB:Fe[je-2]};break;case 34:this.$=xe.Cardinality.ZERO_OR_ONE;break;case 35:this.$=xe.Cardinality.ZERO_OR_MORE;break;case 36:this.$=xe.Cardinality.ONE_OR_MORE;break;case 37:this.$=xe.Cardinality.ONLY_ONE;break;case 38:this.$=xe.Cardinality.MD_PARENT;break;case 39:this.$=xe.Identification.NON_IDENTIFYING;break;case 40:this.$=xe.Identification.IDENTIFYING;break}},table:[{3:1,4:[1,2]},{1:[3]},i(s,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,20:u,22:d,24:p,26:v,27:b,28:y},i(s,[2,7],{1:[2,1]}),i(s,[2,3]),{9:16,11:9,20:u,22:d,24:p,26:v,27:b,28:y},i(s,[2,5]),i(s,[2,6]),i(s,[2,11],{12:17,39:20,15:[1,18],18:[1,19],41:T,42:_,43:A,44:P,45:R}),{21:[1,26]},{23:[1,27]},{25:[1,28]},i(s,[2,18]),i(F,[2,19]),i(F,[2,20]),i(s,[2,4]),{11:29,27:b,28:y},{16:30,17:[1,31],29:32,30:33,34:j},{11:35,27:b,28:y},{40:36,46:[1,37],47:[1,38]},i(K,[2,34]),i(K,[2,35]),i(K,[2,36]),i(K,[2,37]),i(K,[2,38]),i(s,[2,15]),i(s,[2,16]),i(s,[2,17]),{13:[1,39]},{17:[1,40]},i(s,[2,10]),{16:41,17:[2,21],29:32,30:33,34:j},{31:42,34:[1,43]},{34:[2,27]},{19:[1,44]},{39:45,41:T,42:_,43:A,44:P,45:R},i(ee,[2,39]),i(ee,[2,40]),{14:46,27:[1,49],28:[1,48],48:[1,47]},i(s,[2,9]),{17:[2,22]},i(ie,[2,23],{32:50,33:51,35:52,37:oe,38:pe}),i([17,34,37,38],[2,28]),i(s,[2,14],{15:[1,55]}),i([27,28],[2,33]),i(s,[2,8]),i(s,[2,41]),i(s,[2,42]),i(s,[2,43]),i(ie,[2,24],{33:56,36:[1,57],38:pe}),i(ie,[2,25]),i(be,[2,29]),i(ie,[2,32]),i(be,[2,31]),{16:58,17:[1,59],29:32,30:33,34:j},i(ie,[2,26]),{35:60,37:oe},{17:[1,61]},i(s,[2,13]),i(be,[2,30]),i(s,[2,12])],defaultActions:{34:[2,27],41:[2,22]},parseError:function(X,ge){if(ge.recoverable)this.trace(X);else{var W=new Error(X);throw W.hash=ge,W}},parse:function(X){var ge=this,W=[0],xe=[],U=[null],Fe=[],Pe=this.table,je="",Ie=0,Se=0,Ce=2,ke=1,Ke=Fe.slice.call(arguments,1),Ft=Object.create(this.lexer),Ne={yy:{}};for(var gn in this.yy)Object.prototype.hasOwnProperty.call(this.yy,gn)&&(Ne.yy[gn]=this.yy[gn]);Ft.setInput(X,Ne.yy),Ne.yy.lexer=Ft,Ne.yy.parser=this,typeof Ft.yylloc>"u"&&(Ft.yylloc={});var _t=Ft.yylloc;Fe.push(_t);var Et=Ft.options&&Ft.options.ranges;typeof Ne.yy.parseError=="function"?this.parseError=Ne.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Gt(){var ji;return ji=xe.pop()||Ft.lex()||ke,typeof ji!="number"&&(ji instanceof Array&&(xe=ji,ji=xe.pop()),ji=ge.symbols_[ji]||ji),ji}for(var ln,xt,Pt,Qe,Dt={},kt,On,ht,zr;;){if(xt=W[W.length-1],this.defaultActions[xt]?Pt=this.defaultActions[xt]:((ln===null||typeof ln>"u")&&(ln=Gt()),Pt=Pe[xt]&&Pe[xt][ln]),typeof Pt>"u"||!Pt.length||!Pt[0]){var yt="";zr=[];for(kt in Pe[xt])this.terminals_[kt]&&kt>Ce&&zr.push("'"+this.terminals_[kt]+"'");Ft.showPosition?yt="Parse error on line "+(Ie+1)+`: +`+Ft.showPosition()+` +Expecting `+zr.join(", ")+", got '"+(this.terminals_[ln]||ln)+"'":yt="Parse error on line "+(Ie+1)+": Unexpected "+(ln==ke?"end of input":"'"+(this.terminals_[ln]||ln)+"'"),this.parseError(yt,{text:Ft.match,token:this.terminals_[ln]||ln,line:Ft.yylineno,loc:_t,expected:zr})}if(Pt[0]instanceof Array&&Pt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+xt+", token: "+ln);switch(Pt[0]){case 1:W.push(ln),U.push(Ft.yytext),Fe.push(Ft.yylloc),W.push(Pt[1]),ln=null,Se=Ft.yyleng,je=Ft.yytext,Ie=Ft.yylineno,_t=Ft.yylloc;break;case 2:if(On=this.productions_[Pt[1]][1],Dt.$=U[U.length-On],Dt._$={first_line:Fe[Fe.length-(On||1)].first_line,last_line:Fe[Fe.length-1].last_line,first_column:Fe[Fe.length-(On||1)].first_column,last_column:Fe[Fe.length-1].last_column},Et&&(Dt._$.range=[Fe[Fe.length-(On||1)].range[0],Fe[Fe.length-1].range[1]]),Qe=this.performAction.apply(Dt,[je,Se,Ie,Ne.yy,Pt[1],U,Fe].concat(Ke)),typeof Qe<"u")return Qe;On&&(W=W.slice(0,-1*On*2),U=U.slice(0,-1*On),Fe=Fe.slice(0,-1*On)),W.push(this.productions_[Pt[1]][0]),U.push(Dt.$),Fe.push(Dt._$),ht=Pe[W[W.length-2]][W[W.length-1]],W.push(ht);break;case 3:return!0}}return!0}},ne=function(){var de={EOF:1,parseError:function(ge,W){if(this.yy.parser)this.yy.parser.parseError(ge,W);else throw new Error(ge)},setInput:function(X,ge){return this.yy=ge||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},input:function(){var X=this._input[0];this.yytext+=X,this.yyleng++,this.offset++,this.match+=X,this.matched+=X;var ge=X.match(/(?:\r\n?|\n).*/g);return ge?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),X},unput:function(X){var ge=X.length,W=X.split(/(?:\r\n?|\n)/g);this._input=X+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-ge),this.offset-=ge;var xe=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),W.length-1&&(this.yylineno-=W.length-1);var U=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:W?(W.length===xe.length?this.yylloc.first_column:0)+xe[xe.length-W.length].length-W[0].length:this.yylloc.first_column-ge},this.options.ranges&&(this.yylloc.range=[U[0],U[0]+this.yyleng-ge]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(X){this.unput(this.match.slice(X))},pastInput:function(){var X=this.matched.substr(0,this.matched.length-this.match.length);return(X.length>20?"...":"")+X.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var X=this.pastInput(),ge=new Array(X.length+1).join("-");return X+this.upcomingInput()+` +`+ge+"^"},test_match:function(X,ge){var W,xe,U;if(this.options.backtrack_lexer&&(U={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&&(U.yylloc.range=this.yylloc.range.slice(0))),xe=X[0].match(/(?:\r\n?|\n).*/g),xe&&(this.yylineno+=xe.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:xe?xe[xe.length-1].length-xe[xe.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],W=this.performAction.call(this,this.yy,this,ge,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),W)return W;if(this._backtrack){for(var Fe in U)this[Fe]=U[Fe];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var X,ge,W,xe;this._more||(this.yytext="",this.match="");for(var U=this._currentRules(),Fe=0;Fege[0].length)){if(ge=W,xe=Fe,this.options.backtrack_lexer){if(X=this.test_match(W,U[Fe]),X!==!1)return X;if(this._backtrack){ge=!1;continue}else return!1}else if(!this.options.flex)break}return ge?(X=this.test_match(ge,U[xe]),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})},lex:function(){var ge=this.next();return ge||this.lex()},begin:function(ge){this.conditionStack.push(ge)},popState:function(){var ge=this.conditionStack.length-1;return ge>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(ge){return ge=this.conditionStack.length-1-Math.abs(ge||0),ge>=0?this.conditionStack[ge]:"INITIAL"},pushState:function(ge){this.begin(ge)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(ge,W,xe,U){switch(xe){case 0:return this.begin("acc_title"),22;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),24;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 10;case 8:break;case 9:return 8;case 10:return 28;case 11:return 48;case 12:return 4;case 13:return this.begin("block"),15;case 14:return 36;case 15:break;case 16:return 37;case 17:return 34;case 18:return 34;case 19:return 38;case 20:break;case 21:return this.popState(),17;case 22:return W.yytext[0];case 23:return 18;case 24:return 19;case 25:return 41;case 26:return 43;case 27:return 43;case 28:return 43;case 29:return 41;case 30:return 41;case 31:return 42;case 32:return 42;case 33:return 42;case 34:return 42;case 35:return 42;case 36:return 43;case 37:return 42;case 38:return 43;case 39:return 44;case 40:return 44;case 41:return 44;case 42:return 44;case 43:return 41;case 44:return 42;case 45:return 43;case 46:return 45;case 47:return 46;case 48:return 47;case 49:return 47;case 50:return 46;case 51:return 46;case 52:return 46;case 53:return 27;case 54:return W.yytext[0];case 55:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/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,/^(?:[A-Za-z_][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[14,15,16,17,18,19,20,21,22],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,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],inclusive:!0}}};return de}();ae.lexer=ne;function se(){this.yy={}}return se.prototype=ae,ae.Parser=se,new se}();Vme.parser=Vme;const Len=Vme;let B9={},Ume=[];const Men={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"},Den={NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},RUe=function(i,s=void 0){return B9[i]===void 0?(B9[i]={attributes:[],alias:s},Xe.info("Added new entity :",i)):B9[i]&&!B9[i].alias&&s&&(B9[i].alias=s,Xe.info(`Add alias '${s}' to entity '${i}'`)),B9[i]},Ien={Cardinality:Men,Identification:Den,getConfig:()=>qt().er,addEntity:RUe,addAttributes:function(i,s){let u=RUe(i),d;for(d=s.length-1;d>=0;d--)u.attributes.push(s[d]),Xe.debug("Added attribute ",s[d].attributeName)},getEntities:()=>B9,addRelationship:function(i,s,u,d){let p={entityA:i,roleA:s,entityB:u,relSpec:d};Ume.push(p),Xe.debug("Added new relationship :",p)},getRelationships:()=>Ume,clear:function(){B9={},Ume=[],Pg()},setAccTitle:Bg,getAccTitle:Cp,setAccDescription:Sp,getAccDescription:_p,setDiagramTitle:cm,getDiagramTitle:Ap},U3={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},G3={ERMarkers:U3,insertMarkers:function(i,s){let u;i.append("defs").append("marker").attr("id",U3.MD_PARENT_START).attr("refX",0).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"),i.append("defs").append("marker").attr("id",U3.MD_PARENT_END).attr("refX",19).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"),i.append("defs").append("marker").attr("id",U3.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),i.append("defs").append("marker").attr("id",U3.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),u=i.append("defs").append("marker").attr("id",U3.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),u.append("circle").attr("stroke",s.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),u.append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M9,0 L9,18"),u=i.append("defs").append("marker").attr("id",U3.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),u.append("circle").attr("stroke",s.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),u.append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M21,0 L21,18"),i.append("defs").append("marker").attr("id",U3.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),i.append("defs").append("marker").attr("id",U3.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),u=i.append("defs").append("marker").attr("id",U3.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),u.append("circle").attr("stroke",s.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),u.append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),u=i.append("defs").append("marker").attr("id",U3.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),u.append("circle").attr("stroke",s.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),u.append("path").attr("stroke",s.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")}},Oen=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function Nen(i){return typeof i=="string"&&Oen.test(i)}const Ud=[];for(let i=0;i<256;++i)Ud.push((i+256).toString(16).slice(1));function Pen(i,s=0){return Ud[i[s+0]]+Ud[i[s+1]]+Ud[i[s+2]]+Ud[i[s+3]]+"-"+Ud[i[s+4]]+Ud[i[s+5]]+"-"+Ud[i[s+6]]+Ud[i[s+7]]+"-"+Ud[i[s+8]]+Ud[i[s+9]]+"-"+Ud[i[s+10]]+Ud[i[s+11]]+Ud[i[s+12]]+Ud[i[s+13]]+Ud[i[s+14]]+Ud[i[s+15]]}function Ben(i){if(!Nen(i))throw TypeError("Invalid UUID");let s;const u=new Uint8Array(16);return u[0]=(s=parseInt(i.slice(0,8),16))>>>24,u[1]=s>>>16&255,u[2]=s>>>8&255,u[3]=s&255,u[4]=(s=parseInt(i.slice(9,13),16))>>>8,u[5]=s&255,u[6]=(s=parseInt(i.slice(14,18),16))>>>8,u[7]=s&255,u[8]=(s=parseInt(i.slice(19,23),16))>>>8,u[9]=s&255,u[10]=(s=parseInt(i.slice(24,36),16))/1099511627776&255,u[11]=s/4294967296&255,u[12]=s>>>24&255,u[13]=s>>>16&255,u[14]=s>>>8&255,u[15]=s&255,u}function Fen(i){i=unescape(encodeURIComponent(i));const s=[];for(let u=0;u>>32-s}function qen(i){const s=[1518500249,1859775393,2400959708,3395469782],u=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof i=="string"){const b=unescape(encodeURIComponent(i));i=[];for(let y=0;y>>0;R=P,P=A,A=Gme(_,30)>>>0,_=T,T=K}u[0]=u[0]+T>>>0,u[1]=u[1]+_>>>0,u[2]=u[2]+A>>>0,u[3]=u[3]+P>>>0,u[4]=u[4]+R>>>0}return[u[0]>>24&255,u[0]>>16&255,u[0]>>8&255,u[0]&255,u[1]>>24&255,u[1]>>16&255,u[1]>>8&255,u[1]&255,u[2]>>24&255,u[2]>>16&255,u[2]>>8&255,u[2]&255,u[3]>>24&255,u[3]>>16&255,u[3]>>8&255,u[3]&255,u[4]>>24&255,u[4]>>16&255,u[4]>>8&255,u[4]&255]}const Hen=$en("v5",80,qen),Ven=/[^\dA-Za-z](\W)*/g;let p1={},IR=new Map;const Uen=function(i){const s=Object.keys(i);for(const u of s)p1[u]=i[u]},Gen=(i,s,u)=>{const d=p1.entityPadding/3,p=p1.entityPadding/3,v=p1.fontSize*.85,b=s.node().getBBox(),y=[];let T=!1,_=!1,A=0,P=0,R=0,F=0,j=b.height+d*2,K=1;u.forEach(pe=>{pe.attributeKeyTypeList!==void 0&&pe.attributeKeyTypeList.length>0&&(T=!0),pe.attributeComment!==void 0&&(_=!0)}),u.forEach(pe=>{const be=`${s.node().id}-attr-${K}`;let ae=0;const ne=qF(pe.attributeType),se=i.append("text").classed("er entityLabel",!0).attr("id",`${be}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",qt().fontFamily).style("font-size",v+"px").text(ne),de=i.append("text").classed("er entityLabel",!0).attr("id",`${be}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",qt().fontFamily).style("font-size",v+"px").text(pe.attributeName),X={};X.tn=se,X.nn=de;const ge=se.node().getBBox(),W=de.node().getBBox();if(A=Math.max(A,ge.width),P=Math.max(P,W.width),ae=Math.max(ge.height,W.height),T){const xe=pe.attributeKeyTypeList!==void 0?pe.attributeKeyTypeList.join(","):"",U=i.append("text").classed("er entityLabel",!0).attr("id",`${be}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",qt().fontFamily).style("font-size",v+"px").text(xe);X.kn=U;const Fe=U.node().getBBox();R=Math.max(R,Fe.width),ae=Math.max(ae,Fe.height)}if(_){const xe=i.append("text").classed("er entityLabel",!0).attr("id",`${be}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",qt().fontFamily).style("font-size",v+"px").text(pe.attributeComment||"");X.cn=xe;const U=xe.node().getBBox();F=Math.max(F,U.width),ae=Math.max(ae,U.height)}X.height=ae,y.push(X),j+=ae+d*2,K+=1});let ee=4;T&&(ee+=2),_&&(ee+=2);const ie=A+P+R+F,oe={width:Math.max(p1.minEntityWidth,Math.max(b.width+p1.entityPadding*2,ie+p*ee)),height:u.length>0?j:Math.max(p1.minEntityHeight,b.height+p1.entityPadding*2)};if(u.length>0){const pe=Math.max(0,(oe.width-ie-p*ee)/(ee/2));s.attr("transform","translate("+oe.width/2+","+(d+b.height/2)+")");let be=b.height+d*2,ae="attributeBoxOdd";y.forEach(ne=>{const se=be+d+ne.height/2;ne.tn.attr("transform","translate("+p+","+se+")");const de=i.insert("rect","#"+ne.tn.node().id).classed(`er ${ae}`,!0).attr("x",0).attr("y",be).attr("width",A+p*2+pe).attr("height",ne.height+d*2),X=parseFloat(de.attr("x"))+parseFloat(de.attr("width"));ne.nn.attr("transform","translate("+(X+p)+","+se+")");const ge=i.insert("rect","#"+ne.nn.node().id).classed(`er ${ae}`,!0).attr("x",X).attr("y",be).attr("width",P+p*2+pe).attr("height",ne.height+d*2);let W=parseFloat(ge.attr("x"))+parseFloat(ge.attr("width"));if(T){ne.kn.attr("transform","translate("+(W+p)+","+se+")");const xe=i.insert("rect","#"+ne.kn.node().id).classed(`er ${ae}`,!0).attr("x",W).attr("y",be).attr("width",R+p*2+pe).attr("height",ne.height+d*2);W=parseFloat(xe.attr("x"))+parseFloat(xe.attr("width"))}_&&(ne.cn.attr("transform","translate("+(W+p)+","+se+")"),i.insert("rect","#"+ne.cn.node().id).classed(`er ${ae}`,"true").attr("x",W).attr("y",be).attr("width",F+p*2+pe).attr("height",ne.height+d*2)),be+=ne.height+d*2,ae=ae==="attributeBoxOdd"?"attributeBoxEven":"attributeBoxOdd"})}else oe.height=Math.max(p1.minEntityHeight,j),s.attr("transform","translate("+oe.width/2+","+oe.height/2+")");return oe},Ken=function(i,s,u){const d=Object.keys(s);let p;return d.forEach(function(v){const b=Zen(v,"entity");IR.set(v,b);const y=i.append("g").attr("id",b);p=p===void 0?b:p;const T="text-"+b,_=y.append("text").classed("er entityLabel",!0).attr("id",T).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",qt().fontFamily).style("font-size",p1.fontSize+"px").text(s[v].alias??v),{width:A,height:P}=Gen(y,_,s[v].attributes),F=y.insert("rect","#"+T).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",A).attr("height",P).node().getBBox();u.setNode(b,{width:F.width,height:F.height,shape:"rect",id:b})}),p},Wen=function(i,s){s.nodes().forEach(function(u){u!==void 0&&s.node(u)!==void 0&&i.select("#"+u).attr("transform","translate("+(s.node(u).x-s.node(u).width/2)+","+(s.node(u).y-s.node(u).height/2)+" )")})},jUe=function(i){return(i.entityA+i.roleA+i.entityB).replace(/\s/g,"")},Yen=function(i,s){return i.forEach(function(u){s.setEdge(IR.get(u.entityA),IR.get(u.entityB),{relationship:u},jUe(u))}),i};let $Ue=0;const Xen=function(i,s,u,d,p){$Ue++;const v=u.edge(IR.get(s.entityA),IR.get(s.entityB),jUe(s)),b=k7().x(function(j){return j.x}).y(function(j){return j.y}).curve(FF),y=i.insert("path","#"+d).classed("er relationshipLine",!0).attr("d",b(v.points)).style("stroke",p1.stroke).style("fill","none");s.relSpec.relType===p.db.Identification.NON_IDENTIFYING&&y.attr("stroke-dasharray","8,8");let T="";switch(p1.arrowMarkerAbsolute&&(T=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,T=T.replace(/\(/g,"\\("),T=T.replace(/\)/g,"\\)")),s.relSpec.cardA){case p.db.Cardinality.ZERO_OR_ONE:y.attr("marker-end","url("+T+"#"+G3.ERMarkers.ZERO_OR_ONE_END+")");break;case p.db.Cardinality.ZERO_OR_MORE:y.attr("marker-end","url("+T+"#"+G3.ERMarkers.ZERO_OR_MORE_END+")");break;case p.db.Cardinality.ONE_OR_MORE:y.attr("marker-end","url("+T+"#"+G3.ERMarkers.ONE_OR_MORE_END+")");break;case p.db.Cardinality.ONLY_ONE:y.attr("marker-end","url("+T+"#"+G3.ERMarkers.ONLY_ONE_END+")");break;case p.db.Cardinality.MD_PARENT:y.attr("marker-end","url("+T+"#"+G3.ERMarkers.MD_PARENT_END+")");break}switch(s.relSpec.cardB){case p.db.Cardinality.ZERO_OR_ONE:y.attr("marker-start","url("+T+"#"+G3.ERMarkers.ZERO_OR_ONE_START+")");break;case p.db.Cardinality.ZERO_OR_MORE:y.attr("marker-start","url("+T+"#"+G3.ERMarkers.ZERO_OR_MORE_START+")");break;case p.db.Cardinality.ONE_OR_MORE:y.attr("marker-start","url("+T+"#"+G3.ERMarkers.ONE_OR_MORE_START+")");break;case p.db.Cardinality.ONLY_ONE:y.attr("marker-start","url("+T+"#"+G3.ERMarkers.ONLY_ONE_START+")");break;case p.db.Cardinality.MD_PARENT:y.attr("marker-start","url("+T+"#"+G3.ERMarkers.MD_PARENT_START+")");break}const _=y.node().getTotalLength(),A=y.node().getPointAtLength(_*.5),P="rel"+$Ue,F=i.append("text").classed("er relationshipLabel",!0).attr("id",P).attr("x",A.x).attr("y",A.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",qt().fontFamily).style("font-size",p1.fontSize+"px").text(s.roleA).node().getBBox();i.insert("rect","#"+P).classed("er relationshipLabelBox",!0).attr("x",A.x-F.width/2).attr("y",A.y-F.height/2).attr("width",F.width).attr("height",F.height)},Qen=function(i,s,u,d){p1=qt().er,Xe.info("Drawing ER diagram");const p=qt().securityLevel;let v;p==="sandbox"&&(v=Ir("#i"+s));const y=Ir(p==="sandbox"?v.nodes()[0].contentDocument.body:"body").select(`[id='${s}']`);G3.insertMarkers(y,p1);let T;T=new B0({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:p1.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel(function(){return{}});const _=Ken(y,d.db.getEntities(),T),A=Yen(d.db.getRelationships(),T);qD(T),Wen(y,T),A.forEach(function(K){Xen(y,K,T,_,d)});const P=p1.diagramPadding;Ao.insertTitle(y,"entityTitleText",p1.titleTopMargin,d.db.getDiagramTitle());const R=y.node().getBBox(),F=R.width+P*2,j=R.height+P*2;Ng(y,j,F,p1.useMaxWidth),y.attr("viewBox",`${R.x-P} ${R.y-P} ${F} ${j}`)},Jen="28e9f9db-3c8d-5aa5-9faf-44286ae5937c";function Zen(i="",s=""){const u=i.replace(Ven,"");return`${zUe(s)}${zUe(u)}${Hen(i,Jen)}`}function zUe(i=""){return i.length>0?`${i}-`:""}const etn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:Len,db:Ien,renderer:{setConf:Uen,draw:Qen},styles:i=>` + .entityBox { + fill: ${i.mainBkg}; + stroke: ${i.nodeBorder}; + } + + .attributeBoxOdd { + fill: ${i.attributeBackgroundColorOdd}; + stroke: ${i.nodeBorder}; + } + + .attributeBoxEven { + fill: ${i.attributeBackgroundColorEven}; + stroke: ${i.nodeBorder}; + } + + .relationshipLabelBox { + fill: ${i.tertiaryColor}; + opacity: 0.7; + background-color: ${i.tertiaryColor}; + rect { + opacity: 0.5; + } + } + + .relationshipLine { + stroke: ${i.lineColor}; + } + + .entityTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.textColor}; + } + #MD_PARENT_START { + fill: #f5f5f5 !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; + } + #MD_PARENT_END { + fill: #f5f5f5 !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; + } + +`}},Symbol.toStringTag,{value:"Module"}));var Kme=function(){var i=function(ae,ne,se,de){for(se=se||{},de=ae.length;de--;se[ae[de]]=ne);return se},s=[1,3],u=[1,6],d=[1,4],p=[1,5],v=[2,5],b=[1,12],y=[5,7,13,19,21,23,24,26,28,31,37,40,47],T=[7,13,19,21,23,24,26,28,31,37,40],_=[7,12,13,19,21,23,24,26,28,31,37,40],A=[7,13,47],P=[1,42],R=[1,41],F=[7,13,29,32,35,38,47],j=[1,55],K=[1,56],ee=[1,57],ie=[7,13,32,35,42,47],oe={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,GG:5,document:6,EOF:7,":":8,DIR:9,options:10,body:11,OPT:12,NL:13,line:14,statement:15,commitStatement:16,mergeStatement:17,cherryPickStatement:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,section:24,branchStatement:25,CHECKOUT:26,ref:27,BRANCH:28,ORDER:29,NUM:30,CHERRY_PICK:31,COMMIT_ID:32,STR:33,PARENT_COMMIT:34,COMMIT_TAG:35,EMPTYSTR:36,MERGE:37,COMMIT_TYPE:38,commitType:39,COMMIT:40,commit_arg:41,COMMIT_MSG:42,NORMAL:43,REVERSE:44,HIGHLIGHT:45,ID:46,";":47,$accept:0,$end:1},terminals_:{2:"error",5:"GG",7:"EOF",8:":",9:"DIR",12:"OPT",13:"NL",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"section",26:"CHECKOUT",28:"BRANCH",29:"ORDER",30:"NUM",31:"CHERRY_PICK",32:"COMMIT_ID",33:"STR",34:"PARENT_COMMIT",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",46:"ID",47:";"},productions_:[0,[3,2],[3,3],[3,4],[3,5],[6,0],[6,2],[10,2],[10,1],[11,0],[11,2],[14,2],[14,1],[15,1],[15,1],[15,1],[15,2],[15,2],[15,1],[15,1],[15,1],[15,2],[25,2],[25,4],[18,3],[18,5],[18,5],[18,7],[18,7],[18,5],[18,5],[18,5],[18,7],[18,7],[18,7],[18,7],[17,2],[17,4],[17,4],[17,4],[17,6],[17,6],[17,6],[17,6],[17,6],[17,6],[17,8],[17,8],[17,8],[17,8],[17,8],[17,8],[16,2],[16,3],[16,3],[16,5],[16,5],[16,3],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,3],[16,5],[16,5],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[41,0],[41,1],[39,1],[39,1],[39,1],[27,1],[27,1],[4,1],[4,1],[4,1]],performAction:function(ne,se,de,X,ge,W,xe){var U=W.length-1;switch(ge){case 2:return W[U];case 3:return W[U-1];case 4:return X.setDirection(W[U-3]),W[U-1];case 6:X.setOptions(W[U-1]),this.$=W[U];break;case 7:W[U-1]+=W[U],this.$=W[U-1];break;case 9:this.$=[];break;case 10:W[U-1].push(W[U]),this.$=W[U-1];break;case 11:this.$=W[U-1];break;case 16:this.$=W[U].trim(),X.setAccTitle(this.$);break;case 17:case 18:this.$=W[U].trim(),X.setAccDescription(this.$);break;case 19:X.addSection(W[U].substr(8)),this.$=W[U].substr(8);break;case 21:X.checkout(W[U]);break;case 22:X.branch(W[U]);break;case 23:X.branch(W[U-2],W[U]);break;case 24:X.cherryPick(W[U],"",void 0);break;case 25:X.cherryPick(W[U-2],"",void 0,W[U]);break;case 26:X.cherryPick(W[U-2],"",W[U]);break;case 27:X.cherryPick(W[U-4],"",W[U],W[U-2]);break;case 28:X.cherryPick(W[U-4],"",W[U-2],W[U]);break;case 29:X.cherryPick(W[U],"",W[U-2]);break;case 30:X.cherryPick(W[U],"","");break;case 31:X.cherryPick(W[U-2],"","");break;case 32:X.cherryPick(W[U-4],"","",W[U-2]);break;case 33:X.cherryPick(W[U-4],"","",W[U]);break;case 34:X.cherryPick(W[U-2],"",W[U-4],W[U]);break;case 35:X.cherryPick(W[U-2],"","",W[U]);break;case 36:X.merge(W[U],"","","");break;case 37:X.merge(W[U-2],W[U],"","");break;case 38:X.merge(W[U-2],"",W[U],"");break;case 39:X.merge(W[U-2],"","",W[U]);break;case 40:X.merge(W[U-4],W[U],"",W[U-2]);break;case 41:X.merge(W[U-4],"",W[U],W[U-2]);break;case 42:X.merge(W[U-4],"",W[U-2],W[U]);break;case 43:X.merge(W[U-4],W[U-2],W[U],"");break;case 44:X.merge(W[U-4],W[U-2],"",W[U]);break;case 45:X.merge(W[U-4],W[U],W[U-2],"");break;case 46:X.merge(W[U-6],W[U-4],W[U-2],W[U]);break;case 47:X.merge(W[U-6],W[U],W[U-4],W[U-2]);break;case 48:X.merge(W[U-6],W[U-4],W[U],W[U-2]);break;case 49:X.merge(W[U-6],W[U-2],W[U-4],W[U]);break;case 50:X.merge(W[U-6],W[U],W[U-2],W[U-4]);break;case 51:X.merge(W[U-6],W[U-2],W[U],W[U-4]);break;case 52:X.commit(W[U]);break;case 53:X.commit("","",X.commitType.NORMAL,W[U]);break;case 54:X.commit("","",W[U],"");break;case 55:X.commit("","",W[U],W[U-2]);break;case 56:X.commit("","",W[U-2],W[U]);break;case 57:X.commit("",W[U],X.commitType.NORMAL,"");break;case 58:X.commit("",W[U-2],X.commitType.NORMAL,W[U]);break;case 59:X.commit("",W[U],X.commitType.NORMAL,W[U-2]);break;case 60:X.commit("",W[U-2],W[U],"");break;case 61:X.commit("",W[U],W[U-2],"");break;case 62:X.commit("",W[U-4],W[U-2],W[U]);break;case 63:X.commit("",W[U-4],W[U],W[U-2]);break;case 64:X.commit("",W[U-2],W[U-4],W[U]);break;case 65:X.commit("",W[U],W[U-4],W[U-2]);break;case 66:X.commit("",W[U],W[U-2],W[U-4]);break;case 67:X.commit("",W[U-2],W[U],W[U-4]);break;case 68:X.commit(W[U],"",X.commitType.NORMAL,"");break;case 69:X.commit(W[U],"",X.commitType.NORMAL,W[U-2]);break;case 70:X.commit(W[U-2],"",X.commitType.NORMAL,W[U]);break;case 71:X.commit(W[U-2],"",W[U],"");break;case 72:X.commit(W[U],"",W[U-2],"");break;case 73:X.commit(W[U],W[U-2],X.commitType.NORMAL,"");break;case 74:X.commit(W[U-2],W[U],X.commitType.NORMAL,"");break;case 75:X.commit(W[U-4],"",W[U-2],W[U]);break;case 76:X.commit(W[U-4],"",W[U],W[U-2]);break;case 77:X.commit(W[U-2],"",W[U-4],W[U]);break;case 78:X.commit(W[U],"",W[U-4],W[U-2]);break;case 79:X.commit(W[U],"",W[U-2],W[U-4]);break;case 80:X.commit(W[U-2],"",W[U],W[U-4]);break;case 81:X.commit(W[U-4],W[U],W[U-2],"");break;case 82:X.commit(W[U-4],W[U-2],W[U],"");break;case 83:X.commit(W[U-2],W[U],W[U-4],"");break;case 84:X.commit(W[U],W[U-2],W[U-4],"");break;case 85:X.commit(W[U],W[U-4],W[U-2],"");break;case 86:X.commit(W[U-2],W[U-4],W[U],"");break;case 87:X.commit(W[U-4],W[U],X.commitType.NORMAL,W[U-2]);break;case 88:X.commit(W[U-4],W[U-2],X.commitType.NORMAL,W[U]);break;case 89:X.commit(W[U-2],W[U],X.commitType.NORMAL,W[U-4]);break;case 90:X.commit(W[U],W[U-2],X.commitType.NORMAL,W[U-4]);break;case 91:X.commit(W[U],W[U-4],X.commitType.NORMAL,W[U-2]);break;case 92:X.commit(W[U-2],W[U-4],X.commitType.NORMAL,W[U]);break;case 93:X.commit(W[U-6],W[U-4],W[U-2],W[U]);break;case 94:X.commit(W[U-6],W[U-4],W[U],W[U-2]);break;case 95:X.commit(W[U-6],W[U-2],W[U-4],W[U]);break;case 96:X.commit(W[U-6],W[U],W[U-4],W[U-2]);break;case 97:X.commit(W[U-6],W[U-2],W[U],W[U-4]);break;case 98:X.commit(W[U-6],W[U],W[U-2],W[U-4]);break;case 99:X.commit(W[U-4],W[U-6],W[U-2],W[U]);break;case 100:X.commit(W[U-4],W[U-6],W[U],W[U-2]);break;case 101:X.commit(W[U-2],W[U-6],W[U-4],W[U]);break;case 102:X.commit(W[U],W[U-6],W[U-4],W[U-2]);break;case 103:X.commit(W[U-2],W[U-6],W[U],W[U-4]);break;case 104:X.commit(W[U],W[U-6],W[U-2],W[U-4]);break;case 105:X.commit(W[U],W[U-4],W[U-2],W[U-6]);break;case 106:X.commit(W[U-2],W[U-4],W[U],W[U-6]);break;case 107:X.commit(W[U],W[U-2],W[U-4],W[U-6]);break;case 108:X.commit(W[U-2],W[U],W[U-4],W[U-6]);break;case 109:X.commit(W[U-4],W[U-2],W[U],W[U-6]);break;case 110:X.commit(W[U-4],W[U],W[U-2],W[U-6]);break;case 111:X.commit(W[U-2],W[U-4],W[U-6],W[U]);break;case 112:X.commit(W[U],W[U-4],W[U-6],W[U-2]);break;case 113:X.commit(W[U-2],W[U],W[U-6],W[U-4]);break;case 114:X.commit(W[U],W[U-2],W[U-6],W[U-4]);break;case 115:X.commit(W[U-4],W[U-2],W[U-6],W[U]);break;case 116:X.commit(W[U-4],W[U],W[U-6],W[U-2]);break;case 117:this.$="";break;case 118:this.$=W[U];break;case 119:this.$=X.commitType.NORMAL;break;case 120:this.$=X.commitType.REVERSE;break;case 121:this.$=X.commitType.HIGHLIGHT;break}},table:[{3:1,4:2,5:s,7:u,13:d,47:p},{1:[3]},{3:7,4:2,5:s,7:u,13:d,47:p},{6:8,7:v,8:[1,9],9:[1,10],10:11,13:b},i(y,[2,124]),i(y,[2,125]),i(y,[2,126]),{1:[2,1]},{7:[1,13]},{6:14,7:v,10:11,13:b},{8:[1,15]},i(T,[2,9],{11:16,12:[1,17]}),i(_,[2,8]),{1:[2,2]},{7:[1,18]},{6:19,7:v,10:11,13:b},{7:[2,6],13:[1,22],14:20,15:21,16:23,17:24,18:25,19:[1,26],21:[1,27],23:[1,28],24:[1,29],25:30,26:[1,31],28:[1,35],31:[1,34],37:[1,33],40:[1,32]},i(_,[2,7]),{1:[2,3]},{7:[1,36]},i(T,[2,10]),{4:37,7:u,13:d,47:p},i(T,[2,12]),i(A,[2,13]),i(A,[2,14]),i(A,[2,15]),{20:[1,38]},{22:[1,39]},i(A,[2,18]),i(A,[2,19]),i(A,[2,20]),{27:40,33:P,46:R},i(A,[2,117],{41:43,32:[1,46],33:[1,48],35:[1,44],38:[1,45],42:[1,47]}),{27:49,33:P,46:R},{32:[1,50],35:[1,51]},{27:52,33:P,46:R},{1:[2,4]},i(T,[2,11]),i(A,[2,16]),i(A,[2,17]),i(A,[2,21]),i(F,[2,122]),i(F,[2,123]),i(A,[2,52]),{33:[1,53]},{39:54,43:j,44:K,45:ee},{33:[1,58]},{33:[1,59]},i(A,[2,118]),i(A,[2,36],{32:[1,60],35:[1,62],38:[1,61]}),{33:[1,63]},{33:[1,64],36:[1,65]},i(A,[2,22],{29:[1,66]}),i(A,[2,53],{32:[1,68],38:[1,67],42:[1,69]}),i(A,[2,54],{32:[1,71],35:[1,70],42:[1,72]}),i(ie,[2,119]),i(ie,[2,120]),i(ie,[2,121]),i(A,[2,57],{35:[1,73],38:[1,74],42:[1,75]}),i(A,[2,68],{32:[1,78],35:[1,76],38:[1,77]}),{33:[1,79]},{39:80,43:j,44:K,45:ee},{33:[1,81]},i(A,[2,24],{34:[1,82],35:[1,83]}),{32:[1,84]},{32:[1,85]},{30:[1,86]},{39:87,43:j,44:K,45:ee},{33:[1,88]},{33:[1,89]},{33:[1,90]},{33:[1,91]},{33:[1,92]},{33:[1,93]},{39:94,43:j,44:K,45:ee},{33:[1,95]},{33:[1,96]},{39:97,43:j,44:K,45:ee},{33:[1,98]},i(A,[2,37],{35:[1,100],38:[1,99]}),i(A,[2,38],{32:[1,102],35:[1,101]}),i(A,[2,39],{32:[1,103],38:[1,104]}),{33:[1,105]},{33:[1,106],36:[1,107]},{33:[1,108]},{33:[1,109]},i(A,[2,23]),i(A,[2,55],{32:[1,110],42:[1,111]}),i(A,[2,59],{38:[1,112],42:[1,113]}),i(A,[2,69],{32:[1,115],38:[1,114]}),i(A,[2,56],{32:[1,116],42:[1,117]}),i(A,[2,61],{35:[1,118],42:[1,119]}),i(A,[2,72],{32:[1,121],35:[1,120]}),i(A,[2,58],{38:[1,122],42:[1,123]}),i(A,[2,60],{35:[1,124],42:[1,125]}),i(A,[2,73],{35:[1,127],38:[1,126]}),i(A,[2,70],{32:[1,129],38:[1,128]}),i(A,[2,71],{32:[1,131],35:[1,130]}),i(A,[2,74],{35:[1,133],38:[1,132]}),{39:134,43:j,44:K,45:ee},{33:[1,135]},{33:[1,136]},{33:[1,137]},{33:[1,138]},{39:139,43:j,44:K,45:ee},i(A,[2,25],{35:[1,140]}),i(A,[2,26],{34:[1,141]}),i(A,[2,31],{34:[1,142]}),i(A,[2,29],{34:[1,143]}),i(A,[2,30],{34:[1,144]}),{33:[1,145]},{33:[1,146]},{39:147,43:j,44:K,45:ee},{33:[1,148]},{39:149,43:j,44:K,45:ee},{33:[1,150]},{33:[1,151]},{33:[1,152]},{33:[1,153]},{33:[1,154]},{33:[1,155]},{33:[1,156]},{39:157,43:j,44:K,45:ee},{33:[1,158]},{33:[1,159]},{33:[1,160]},{39:161,43:j,44:K,45:ee},{33:[1,162]},{39:163,43:j,44:K,45:ee},{33:[1,164]},{33:[1,165]},{33:[1,166]},{39:167,43:j,44:K,45:ee},{33:[1,168]},i(A,[2,43],{35:[1,169]}),i(A,[2,44],{38:[1,170]}),i(A,[2,42],{32:[1,171]}),i(A,[2,45],{35:[1,172]}),i(A,[2,40],{38:[1,173]}),i(A,[2,41],{32:[1,174]}),{33:[1,175],36:[1,176]},{33:[1,177]},{33:[1,178]},{33:[1,179]},{33:[1,180]},i(A,[2,66],{42:[1,181]}),i(A,[2,79],{32:[1,182]}),i(A,[2,67],{42:[1,183]}),i(A,[2,90],{38:[1,184]}),i(A,[2,80],{32:[1,185]}),i(A,[2,89],{38:[1,186]}),i(A,[2,65],{42:[1,187]}),i(A,[2,78],{32:[1,188]}),i(A,[2,64],{42:[1,189]}),i(A,[2,84],{35:[1,190]}),i(A,[2,77],{32:[1,191]}),i(A,[2,83],{35:[1,192]}),i(A,[2,63],{42:[1,193]}),i(A,[2,91],{38:[1,194]}),i(A,[2,62],{42:[1,195]}),i(A,[2,85],{35:[1,196]}),i(A,[2,86],{35:[1,197]}),i(A,[2,92],{38:[1,198]}),i(A,[2,76],{32:[1,199]}),i(A,[2,87],{38:[1,200]}),i(A,[2,75],{32:[1,201]}),i(A,[2,81],{35:[1,202]}),i(A,[2,82],{35:[1,203]}),i(A,[2,88],{38:[1,204]}),{33:[1,205]},{39:206,43:j,44:K,45:ee},{33:[1,207]},{33:[1,208]},{39:209,43:j,44:K,45:ee},{33:[1,210]},i(A,[2,27]),i(A,[2,32]),i(A,[2,28]),i(A,[2,33]),i(A,[2,34]),i(A,[2,35]),{33:[1,211]},{33:[1,212]},{33:[1,213]},{39:214,43:j,44:K,45:ee},{33:[1,215]},{39:216,43:j,44:K,45:ee},{33:[1,217]},{33:[1,218]},{33:[1,219]},{33:[1,220]},{33:[1,221]},{33:[1,222]},{33:[1,223]},{39:224,43:j,44:K,45:ee},{33:[1,225]},{33:[1,226]},{33:[1,227]},{39:228,43:j,44:K,45:ee},{33:[1,229]},{39:230,43:j,44:K,45:ee},{33:[1,231]},{33:[1,232]},{33:[1,233]},{39:234,43:j,44:K,45:ee},i(A,[2,46]),i(A,[2,48]),i(A,[2,47]),i(A,[2,49]),i(A,[2,51]),i(A,[2,50]),i(A,[2,107]),i(A,[2,108]),i(A,[2,105]),i(A,[2,106]),i(A,[2,110]),i(A,[2,109]),i(A,[2,114]),i(A,[2,113]),i(A,[2,112]),i(A,[2,111]),i(A,[2,116]),i(A,[2,115]),i(A,[2,104]),i(A,[2,103]),i(A,[2,102]),i(A,[2,101]),i(A,[2,99]),i(A,[2,100]),i(A,[2,98]),i(A,[2,97]),i(A,[2,96]),i(A,[2,95]),i(A,[2,93]),i(A,[2,94])],defaultActions:{7:[2,1],13:[2,2],18:[2,3],36:[2,4]},parseError:function(ne,se){if(se.recoverable)this.trace(ne);else{var de=new Error(ne);throw de.hash=se,de}},parse:function(ne){var se=this,de=[0],X=[],ge=[null],W=[],xe=this.table,U="",Fe=0,Pe=0,je=2,Ie=1,Se=W.slice.call(arguments,1),Ce=Object.create(this.lexer),ke={yy:{}};for(var Ke in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ke)&&(ke.yy[Ke]=this.yy[Ke]);Ce.setInput(ne,ke.yy),ke.yy.lexer=Ce,ke.yy.parser=this,typeof Ce.yylloc>"u"&&(Ce.yylloc={});var Ft=Ce.yylloc;W.push(Ft);var Ne=Ce.options&&Ce.options.ranges;typeof ke.yy.parseError=="function"?this.parseError=ke.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function gn(){var ht;return ht=X.pop()||Ce.lex()||Ie,typeof ht!="number"&&(ht instanceof Array&&(X=ht,ht=X.pop()),ht=se.symbols_[ht]||ht),ht}for(var _t,Et,Gt,ln,xt={},Pt,Qe,Dt,kt;;){if(Et=de[de.length-1],this.defaultActions[Et]?Gt=this.defaultActions[Et]:((_t===null||typeof _t>"u")&&(_t=gn()),Gt=xe[Et]&&xe[Et][_t]),typeof Gt>"u"||!Gt.length||!Gt[0]){var On="";kt=[];for(Pt in xe[Et])this.terminals_[Pt]&&Pt>je&&kt.push("'"+this.terminals_[Pt]+"'");Ce.showPosition?On="Parse error on line "+(Fe+1)+`: +`+Ce.showPosition()+` +Expecting `+kt.join(", ")+", got '"+(this.terminals_[_t]||_t)+"'":On="Parse error on line "+(Fe+1)+": Unexpected "+(_t==Ie?"end of input":"'"+(this.terminals_[_t]||_t)+"'"),this.parseError(On,{text:Ce.match,token:this.terminals_[_t]||_t,line:Ce.yylineno,loc:Ft,expected:kt})}if(Gt[0]instanceof Array&&Gt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Et+", token: "+_t);switch(Gt[0]){case 1:de.push(_t),ge.push(Ce.yytext),W.push(Ce.yylloc),de.push(Gt[1]),_t=null,Pe=Ce.yyleng,U=Ce.yytext,Fe=Ce.yylineno,Ft=Ce.yylloc;break;case 2:if(Qe=this.productions_[Gt[1]][1],xt.$=ge[ge.length-Qe],xt._$={first_line:W[W.length-(Qe||1)].first_line,last_line:W[W.length-1].last_line,first_column:W[W.length-(Qe||1)].first_column,last_column:W[W.length-1].last_column},Ne&&(xt._$.range=[W[W.length-(Qe||1)].range[0],W[W.length-1].range[1]]),ln=this.performAction.apply(xt,[U,Pe,Fe,ke.yy,Gt[1],ge,W].concat(Se)),typeof ln<"u")return ln;Qe&&(de=de.slice(0,-1*Qe*2),ge=ge.slice(0,-1*Qe),W=W.slice(0,-1*Qe)),de.push(this.productions_[Gt[1]][0]),ge.push(xt.$),W.push(xt._$),Dt=xe[de[de.length-2]][de[de.length-1]],de.push(Dt);break;case 3:return!0}}return!0}},pe=function(){var ae={EOF:1,parseError:function(se,de){if(this.yy.parser)this.yy.parser.parseError(se,de);else throw new Error(se)},setInput:function(ne,se){return this.yy=se||this.yy||{},this._input=ne,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},input:function(){var ne=this._input[0];this.yytext+=ne,this.yyleng++,this.offset++,this.match+=ne,this.matched+=ne;var se=ne.match(/(?:\r\n?|\n).*/g);return se?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),ne},unput:function(ne){var se=ne.length,de=ne.split(/(?:\r\n?|\n)/g);this._input=ne+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-se),this.offset-=se;var X=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 ge=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===X.length?this.yylloc.first_column:0)+X[X.length-de.length].length-de[0].length:this.yylloc.first_column-se},this.options.ranges&&(this.yylloc.range=[ge[0],ge[0]+this.yyleng-se]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(ne){this.unput(this.match.slice(ne))},pastInput:function(){var ne=this.matched.substr(0,this.matched.length-this.match.length);return(ne.length>20?"...":"")+ne.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var ne=this.match;return ne.length<20&&(ne+=this._input.substr(0,20-ne.length)),(ne.substr(0,20)+(ne.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var ne=this.pastInput(),se=new Array(ne.length+1).join("-");return ne+this.upcomingInput()+` +`+se+"^"},test_match:function(ne,se){var de,X,ge;if(this.options.backtrack_lexer&&(ge={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&&(ge.yylloc.range=this.yylloc.range.slice(0))),X=ne[0].match(/(?:\r\n?|\n).*/g),X&&(this.yylineno+=X.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:X?X[X.length-1].length-X[X.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+ne[0].length},this.yytext+=ne[0],this.match+=ne[0],this.matches=ne,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(ne[0].length),this.matched+=ne[0],de=this.performAction.call(this,this.yy,this,se,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),de)return de;if(this._backtrack){for(var W in ge)this[W]=ge[W];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var ne,se,de,X;this._more||(this.yytext="",this.match="");for(var ge=this._currentRules(),W=0;Wse[0].length)){if(se=de,X=W,this.options.backtrack_lexer){if(ne=this.test_match(de,ge[W]),ne!==!1)return ne;if(this._backtrack){se=!1;continue}else return!1}else if(!this.options.flex)break}return se?(ne=this.test_match(se,ge[X]),ne!==!1?ne:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var se=this.next();return se||this.lex()},begin:function(se){this.conditionStack.push(se)},popState:function(){var se=this.conditionStack.length-1;return se>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(se){return se=this.conditionStack.length-1-Math.abs(se||0),se>=0?this.conditionStack[se]:"INITIAL"},pushState:function(se){this.begin(se)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(se,de,X,ge){switch(X){case 0:return this.begin("acc_title"),19;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),21;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 13;case 8:break;case 9:break;case 10:return 5;case 11:return 40;case 12:return 32;case 13:return 38;case 14:return 42;case 15:return 43;case 16:return 44;case 17:return 45;case 18:return 35;case 19:return 28;case 20:return 29;case 21:return 37;case 22:return 31;case 23:return 34;case 24:return 26;case 25:return 9;case 26:return 9;case 27:return 8;case 28:return"CARET";case 29:this.begin("options");break;case 30:this.popState();break;case 31:return 12;case 32:return 36;case 33:this.begin("string");break;case 34:this.popState();break;case 35:return 33;case 36:return 30;case 37:return 46;case 38:return 7}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:parent:)/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:TB\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},options:{rules:[30,31],inclusive:!1},string:{rules:[34,35],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32,33,36,37,38,39],inclusive:!0}}};return ae}();oe.lexer=pe;function be(){this.yy={}}return be.prototype=oe,oe.Parser=be,new be}();Kme.parser=Kme;const ttn=Kme;let oJ=qt().gitGraph.mainBranchName,ntn=qt().gitGraph.mainBranchOrder,b1={},Np=null,OR={};OR[oJ]={name:oJ,order:ntn};let F0={};F0[oJ]=Np;let sd=oJ,qUe="LR",YC=0;function Wme(){return mje({length:7})}function rtn(i,s){const u=Object.create(null);return i.reduce((d,p)=>{const v=s(p);return u[v]||(u[v]=!0,d.push(p)),d},[])}const itn=function(i){qUe=i};let HUe={};const stn=function(i){Xe.debug("options str",i),i=i&&i.trim(),i=i||"{}";try{HUe=JSON.parse(i)}catch(s){Xe.error("error while parsing gitGraph options",s.message)}},atn=function(){return HUe},otn=function(i,s,u,d){Xe.debug("Entering commit:",i,s,u,d),s=ci.sanitizeText(s,qt()),i=ci.sanitizeText(i,qt()),d=ci.sanitizeText(d,qt());const p={id:s||YC+"-"+Wme(),message:i,seq:YC++,type:u||UD.NORMAL,tag:d||"",parents:Np==null?[]:[Np.id],branch:sd};Np=p,b1[p.id]=p,F0[sd]=p.id,Xe.debug("in pushCommit "+p.id)},ctn=function(i,s){if(i=ci.sanitizeText(i,qt()),F0[i]===void 0)F0[i]=Np!=null?Np.id:null,OR[i]={name:i,order:s?parseInt(s,10):null},VUe(i),Xe.debug("in createBranch");else{let u=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 '+i+'")');throw u.hash={text:"branch "+i,token:"branch "+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+i+'"']},u}},utn=function(i,s,u,d){i=ci.sanitizeText(i,qt()),s=ci.sanitizeText(s,qt());const p=b1[F0[sd]],v=b1[F0[i]];if(sd===i){let y=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw y.hash={text:"merge "+i,token:"merge "+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},y}else if(p===void 0||!p){let y=new Error('Incorrect usage of "merge". Current branch ('+sd+")has no commits");throw y.hash={text:"merge "+i,token:"merge "+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},y}else if(F0[i]===void 0){let y=new Error('Incorrect usage of "merge". Branch to be merged ('+i+") does not exist");throw y.hash={text:"merge "+i,token:"merge "+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+i]},y}else if(v===void 0||!v){let y=new Error('Incorrect usage of "merge". Branch to be merged ('+i+") has no commits");throw y.hash={text:"merge "+i,token:"merge "+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},y}else if(p===v){let y=new Error('Incorrect usage of "merge". Both branches have same head');throw y.hash={text:"merge "+i,token:"merge "+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},y}else if(s&&b1[s]!==void 0){let y=new Error('Incorrect usage of "merge". Commit with id:'+s+" already exists, use different custom Id");throw y.hash={text:"merge "+i+s+u+d,token:"merge "+i+s+u+d,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+i+" "+s+"_UNIQUE "+u+" "+d]},y}const b={id:s||YC+"-"+Wme(),message:"merged branch "+i+" into "+sd,seq:YC++,parents:[Np==null?null:Np.id,F0[i]],branch:sd,type:UD.MERGE,customType:u,customId:!!s,tag:d||""};Np=b,b1[b.id]=b,F0[sd]=b.id,Xe.debug(F0),Xe.debug("in mergeBranch")},ltn=function(i,s,u,d){if(Xe.debug("Entering cherryPick:",i,s,u),i=ci.sanitizeText(i,qt()),s=ci.sanitizeText(s,qt()),u=ci.sanitizeText(u,qt()),d=ci.sanitizeText(d,qt()),!i||b1[i]===void 0){let b=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw b.hash={text:"cherryPick "+i+" "+s,token:"cherryPick "+i+" "+s,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},b}let p=b1[i],v=p.branch;if(d&&!(Array.isArray(p.parents)&&p.parents.includes(d)))throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.");if(p.type===UD.MERGE&&!d)throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.");if(!s||b1[s]===void 0){if(v===sd){let T=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw T.hash={text:"cherryPick "+i+" "+s,token:"cherryPick "+i+" "+s,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},T}const b=b1[F0[sd]];if(b===void 0||!b){let T=new Error('Incorrect usage of "cherry-pick". Current branch ('+sd+")has no commits");throw T.hash={text:"cherryPick "+i+" "+s,token:"cherryPick "+i+" "+s,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},T}const y={id:YC+"-"+Wme(),message:"cherry-picked "+p+" into "+sd,seq:YC++,parents:[Np==null?null:Np.id,p.id],branch:sd,type:UD.CHERRY_PICK,tag:u??`cherry-pick:${p.id}${p.type===UD.MERGE?`|parent:${d}`:""}`};Np=y,b1[y.id]=y,F0[sd]=y.id,Xe.debug(F0),Xe.debug("in cherryPick")}},VUe=function(i){if(i=ci.sanitizeText(i,qt()),F0[i]===void 0){let s=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+i+'")');throw s.hash={text:"checkout "+i,token:"checkout "+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+i+'"']},s}else{sd=i;const s=F0[sd];Np=b1[s]}};function UUe(i,s,u){const d=i.indexOf(s);d===-1?i.push(u):i.splice(d,1,u)}function GUe(i){const s=i.reduce((p,v)=>p.seq>v.seq?p:v,i[0]);let u="";i.forEach(function(p){p===s?u+=" *":u+=" |"});const d=[u,s.id,s.seq];for(let p in F0)F0[p]===s.id&&d.push(p);if(Xe.debug(d.join(" ")),s.parents&&s.parents.length==2){const p=b1[s.parents[0]];UUe(i,s,p),i.push(b1[s.parents[1]])}else{if(s.parents.length==0)return;{const p=b1[s.parents];UUe(i,s,p)}}i=rtn(i,p=>p.id),GUe(i)}const htn=function(){Xe.debug(b1);const i=KUe()[0];GUe([i])},ftn=function(){b1={},Np=null;let i=qt().gitGraph.mainBranchName,s=qt().gitGraph.mainBranchOrder;F0={},F0[i]=null,OR={},OR[i]={name:i,order:s},sd=i,YC=0,Pg()},dtn=function(){return Object.values(OR).map((s,u)=>s.order!==null?s:{...s,order:parseFloat(`0.${u}`,10)}).sort((s,u)=>s.order-u.order).map(({name:s})=>({name:s}))},gtn=function(){return F0},ptn=function(){return b1},KUe=function(){const i=Object.keys(b1).map(function(s){return b1[s]});return i.forEach(function(s){Xe.debug(s.id)}),i.sort((s,u)=>s.seq-u.seq),i},btn=function(){return sd},mtn=function(){return qUe},vtn=function(){return Np},UD={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},wtn={getConfig:()=>qt().gitGraph,setDirection:itn,setOptions:stn,getOptions:atn,commit:otn,branch:ctn,merge:utn,cherryPick:ltn,checkout:VUe,prettyPrint:htn,clear:ftn,getBranchesAsObjArray:dtn,getBranches:gtn,getCommits:ptn,getCommitsArray:KUe,getCurrentBranch:btn,getDirection:mtn,getHead:vtn,setAccTitle:Bg,getAccTitle:Cp,getAccDescription:_p,setAccDescription:Sp,setDiagramTitle:cm,getDiagramTitle:Ap,commitType:UD};let NR={};const ad={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},XC=8;let H2={},H7={},cJ=[],PR=0,R0="LR";const ytn=()=>{H2={},H7={},NR={},PR=0,cJ=[],R0="LR"},WUe=i=>{const s=document.createElementNS("http://www.w3.org/2000/svg","text");let u=[];typeof i=="string"?u=i.split(/\\n|\n|/gi):Array.isArray(i)?u=i:u=[];for(const d of u){const p=document.createElementNS("http://www.w3.org/2000/svg","tspan");p.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),p.setAttribute("dy","1em"),p.setAttribute("x","0"),p.setAttribute("class","row"),p.textContent=d.trim(),s.appendChild(p)}return s},xtn=i=>{let s="",u=0;return i.forEach(d=>{const p=R0==="TB"?H7[d].y:H7[d].x;p>=u&&(s=d,u=p)}),s||void 0},YUe=(i,s,u)=>{const d=qt().gitGraph,p=i.append("g").attr("class","commit-bullets"),v=i.append("g").attr("class","commit-labels");let b=0;R0==="TB"&&(b=30);const T=Object.keys(s).sort((R,F)=>s[R].seq-s[F].seq),_=d.parallelCommits,A=10,P=40;T.forEach(R=>{const F=s[R];if(_)if(F.parents.length){const ie=xtn(F.parents);b=R0==="TB"?H7[ie].y+P:H7[ie].x+P}else b=0,R0==="TB"&&(b=30);const j=b+A,K=R0==="TB"?j:H2[F.branch].pos,ee=R0==="TB"?H2[F.branch].pos:j;if(u){let ie,oe=F.customType!==void 0&&F.customType!==""?F.customType:F.type;switch(oe){case ad.NORMAL:ie="commit-normal";break;case ad.REVERSE:ie="commit-reverse";break;case ad.HIGHLIGHT:ie="commit-highlight";break;case ad.MERGE:ie="commit-merge";break;case ad.CHERRY_PICK:ie="commit-cherry-pick";break;default:ie="commit-normal"}if(oe===ad.HIGHLIGHT){const pe=p.append("rect");pe.attr("x",ee-10),pe.attr("y",K-10),pe.attr("height",20),pe.attr("width",20),pe.attr("class",`commit ${F.id} commit-highlight${H2[F.branch].index%XC} ${ie}-outer`),p.append("rect").attr("x",ee-6).attr("y",K-6).attr("height",12).attr("width",12).attr("class",`commit ${F.id} commit${H2[F.branch].index%XC} ${ie}-inner`)}else if(oe===ad.CHERRY_PICK)p.append("circle").attr("cx",ee).attr("cy",K).attr("r",10).attr("class",`commit ${F.id} ${ie}`),p.append("circle").attr("cx",ee-3).attr("cy",K+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${F.id} ${ie}`),p.append("circle").attr("cx",ee+3).attr("cy",K+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${F.id} ${ie}`),p.append("line").attr("x1",ee+3).attr("y1",K+1).attr("x2",ee).attr("y2",K-5).attr("stroke","#fff").attr("class",`commit ${F.id} ${ie}`),p.append("line").attr("x1",ee-3).attr("y1",K+1).attr("x2",ee).attr("y2",K-5).attr("stroke","#fff").attr("class",`commit ${F.id} ${ie}`);else{const pe=p.append("circle");if(pe.attr("cx",ee),pe.attr("cy",K),pe.attr("r",F.type===ad.MERGE?9:10),pe.attr("class",`commit ${F.id} commit${H2[F.branch].index%XC}`),oe===ad.MERGE){const be=p.append("circle");be.attr("cx",ee),be.attr("cy",K),be.attr("r",6),be.attr("class",`commit ${ie} ${F.id} commit${H2[F.branch].index%XC}`)}oe===ad.REVERSE&&p.append("path").attr("d",`M ${ee-5},${K-5}L${ee+5},${K+5}M${ee-5},${K+5}L${ee+5},${K-5}`).attr("class",`commit ${ie} ${F.id} commit${H2[F.branch].index%XC}`)}}if(R0==="TB"?H7[F.id]={x:ee,y:j}:H7[F.id]={x:j,y:K},u){if(F.type!==ad.CHERRY_PICK&&(F.customId&&F.type===ad.MERGE||F.type!==ad.MERGE)&&d.showCommitLabel){const pe=v.append("g"),be=pe.insert("rect").attr("class","commit-label-bkg"),ae=pe.append("text").attr("x",b).attr("y",K+25).attr("class","commit-label").text(F.id);let ne=ae.node().getBBox();if(be.attr("x",j-ne.width/2-2).attr("y",K+13.5).attr("width",ne.width+2*2).attr("height",ne.height+2*2),R0==="TB"&&(be.attr("x",ee-(ne.width+4*4+5)).attr("y",K-12),ae.attr("x",ee-(ne.width+4*4)).attr("y",K+ne.height-12)),R0!=="TB"&&ae.attr("x",j-ne.width/2),d.rotateCommitLabel)if(R0==="TB")ae.attr("transform","rotate(-45, "+ee+", "+K+")"),be.attr("transform","rotate(-45, "+ee+", "+K+")");else{let se=-7.5-(ne.width+10)/25*9.5,de=10+ne.width/25*8.5;pe.attr("transform","translate("+se+", "+de+") rotate(-45, "+b+", "+K+")")}}if(F.tag){const pe=v.insert("polygon"),be=v.append("circle"),ae=v.append("text").attr("y",K-16).attr("class","tag-label").text(F.tag);let ne=ae.node().getBBox();ae.attr("x",j-ne.width/2);const se=ne.height/2,de=K-19.2;pe.attr("class","tag-label-bkg").attr("points",` + ${b-ne.width/2-4/2},${de+2} + ${b-ne.width/2-4/2},${de-2} + ${j-ne.width/2-4},${de-se-2} + ${j+ne.width/2+4},${de-se-2} + ${j+ne.width/2+4},${de+se+2} + ${j-ne.width/2-4},${de+se+2}`),be.attr("cx",b-ne.width/2+4/2).attr("cy",de).attr("r",1.5).attr("class","tag-hole"),R0==="TB"&&(pe.attr("class","tag-label-bkg").attr("points",` + ${ee},${b+2} + ${ee},${b-2} + ${ee+A},${b-se-2} + ${ee+A+ne.width+4},${b-se-2} + ${ee+A+ne.width+4},${b+se+2} + ${ee+A},${b+se+2}`).attr("transform","translate(12,12) rotate(45, "+ee+","+b+")"),be.attr("cx",ee+4/2).attr("cy",b).attr("transform","translate(12,12) rotate(45, "+ee+","+b+")"),ae.attr("x",ee+5).attr("y",b+3).attr("transform","translate(14,14) rotate(45, "+ee+","+b+")"))}}b+=P+A,b>PR&&(PR=b)})},ktn=(i,s,u,d,p)=>{const b=(R0==="TB"?u.x_.branch===b,T=_=>_.seq>i.seq&&_.seqT(_)&&y(_))},BR=(i,s,u=0)=>{const d=i+Math.abs(i-s)/2;if(u>5)return d;if(cJ.every(b=>Math.abs(b-d)>=10))return cJ.push(d),d;const v=Math.abs(i-s);return BR(i,s-v/5,u+1)},Etn=(i,s,u,d)=>{const p=H7[s.id],v=H7[u.id],b=ktn(s,u,p,v,d);let y="",T="",_=0,A=0,P=H2[u.branch].index;u.type===ad.MERGE&&s.id!==u.parents[0]&&(P=H2[s.branch].index);let R;if(b){y="A 10 10, 0, 0, 0,",T="A 10 10, 0, 0, 1,",_=10,A=10;const F=p.yv.x&&(y="A 20 20, 0, 0, 0,",T="A 20 20, 0, 0, 1,",_=20,A=20,u.type===ad.MERGE&&s.id!==u.parents[0]?R=`M ${p.x} ${p.y} L ${p.x} ${v.y-_} ${T} ${p.x-A} ${v.y} L ${v.x} ${v.y}`:R=`M ${p.x} ${p.y} L ${v.x+_} ${p.y} ${y} ${v.x} ${p.y+A} L ${v.x} ${v.y}`),p.x===v.x&&(R=`M ${p.x} ${p.y} L ${v.x} ${v.y}`)):(p.yv.y&&(u.type===ad.MERGE&&s.id!==u.parents[0]?R=`M ${p.x} ${p.y} L ${v.x-_} ${p.y} ${y} ${v.x} ${p.y-A} L ${v.x} ${v.y}`:R=`M ${p.x} ${p.y} L ${p.x} ${v.y+_} ${T} ${p.x+A} ${v.y} L ${v.x} ${v.y}`),p.y===v.y&&(R=`M ${p.x} ${p.y} L ${v.x} ${v.y}`));i.append("path").attr("d",R).attr("class","arrow arrow"+P%XC)},Ttn=(i,s)=>{const u=i.append("g").attr("class","commit-arrows");Object.keys(s).forEach(d=>{const p=s[d];p.parents&&p.parents.length>0&&p.parents.forEach(v=>{Etn(u,s[v],p,s)})})},Ctn=(i,s)=>{const u=qt().gitGraph,d=i.append("g");s.forEach((p,v)=>{const b=v%XC,y=H2[p.name].pos,T=d.append("line");T.attr("x1",0),T.attr("y1",y),T.attr("x2",PR),T.attr("y2",y),T.attr("class","branch branch"+b),R0==="TB"&&(T.attr("y1",30),T.attr("x1",y),T.attr("y2",PR),T.attr("x2",y)),cJ.push(y);let _=p.name;const A=WUe(_),P=d.insert("rect"),F=d.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+b);F.node().appendChild(A);let j=A.getBBox();P.attr("class","branchLabelBkg label"+b).attr("rx",4).attr("ry",4).attr("x",-j.width-4-(u.rotateCommitLabel===!0?30:0)).attr("y",-j.height/2+8).attr("width",j.width+18).attr("height",j.height+4),F.attr("transform","translate("+(-j.width-14-(u.rotateCommitLabel===!0?30:0))+", "+(y-j.height/2-1)+")"),R0==="TB"&&(P.attr("x",y-j.width/2-10).attr("y",0),F.attr("transform","translate("+(y-j.width/2-5)+", 0)")),R0!=="TB"&&P.attr("transform","translate(-19, "+(y-j.height/2)+")")})},Stn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:ttn,db:wtn,renderer:{draw:function(i,s,u,d){ytn();const p=qt(),v=p.gitGraph;Xe.debug("in gitgraph renderer",i+` +`,"id:",s,u),NR=d.db.getCommits();const b=d.db.getBranchesAsObjArray();R0=d.db.getDirection();const y=Ir(`[id="${s}"]`);let T=0;b.forEach((_,A)=>{const P=WUe(_.name),R=y.append("g"),F=R.insert("g").attr("class","branchLabel"),j=F.insert("g").attr("class","label branch-label");j.node().appendChild(P);let K=P.getBBox();H2[_.name]={pos:T,index:A},T+=50+(v.rotateCommitLabel?40:0)+(R0==="TB"?K.width/2:0),j.remove(),F.remove(),R.remove()}),YUe(y,NR,!1),v.showBranches&&Ctn(y,b),Ttn(y,NR),YUe(y,NR,!0),Ao.insertTitle(y,"gitTitleText",v.titleTopMargin,d.db.getDiagramTitle()),e$e(void 0,y,v.diagramPadding,v.useMaxWidth??p.useMaxWidth)}},styles:i=>` + .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(s=>` + .branch-label${s} { fill: ${i["gitBranchLabel"+s]}; } + .commit${s} { stroke: ${i["git"+s]}; fill: ${i["git"+s]}; } + .commit-highlight${s} { stroke: ${i["gitInv"+s]}; fill: ${i["gitInv"+s]}; } + .label${s} { fill: ${i["git"+s]}; } + .arrow${s} { stroke: ${i["git"+s]}; } + `).join(` +`)} + + .branch { + stroke-width: 1; + stroke: ${i.lineColor}; + stroke-dasharray: 2; + } + .commit-label { font-size: ${i.commitLabelFontSize}; fill: ${i.commitLabelColor};} + .commit-label-bkg { font-size: ${i.commitLabelFontSize}; fill: ${i.commitLabelBackground}; opacity: 0.5; } + .tag-label { font-size: ${i.tagLabelFontSize}; fill: ${i.tagLabelColor};} + .tag-label-bkg { fill: ${i.tagLabelBackground}; stroke: ${i.tagLabelBorder}; } + .tag-hole { fill: ${i.textColor}; } + + .commit-merge { + stroke: ${i.primaryColor}; + fill: ${i.primaryColor}; + } + .commit-reverse { + stroke: ${i.primaryColor}; + fill: ${i.primaryColor}; + stroke-width: 3; + } + .commit-highlight-outer { + } + .commit-highlight-inner { + stroke: ${i.primaryColor}; + fill: ${i.primaryColor}; + } + + .arrow { stroke-width: 8; stroke-linecap: round; fill: none} + .gitTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.textColor}; + } +`}},Symbol.toStringTag,{value:"Module"}));var Yme=function(){var i=function(W,xe,U,Fe){for(U=U||{},Fe=W.length;Fe--;U[W[Fe]]=xe);return U},s=[6,8,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,30,32,33,35,37],u=[1,25],d=[1,26],p=[1,27],v=[1,28],b=[1,29],y=[1,30],T=[1,31],_=[1,9],A=[1,10],P=[1,11],R=[1,12],F=[1,13],j=[1,14],K=[1,15],ee=[1,16],ie=[1,18],oe=[1,19],pe=[1,20],be=[1,21],ae=[1,22],ne=[1,24],se=[1,32],de={trace:function(){},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,dateFormat:19,inclusiveEndDates:20,topAxis:21,axisFormat:22,tickInterval:23,excludes:24,includes:25,todayMarker:26,title:27,acc_title:28,acc_title_value:29,acc_descr:30,acc_descr_value:31,acc_descr_multiline_value:32,section:33,clickStatement:34,taskTxt:35,taskData:36,click:37,callbackname:38,callbackargs:39,href:40,clickStatementDebug:41,$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",19:"dateFormat",20:"inclusiveEndDates",21:"topAxis",22:"axisFormat",23:"tickInterval",24:"excludes",25:"includes",26:"todayMarker",27:"title",28:"acc_title",29:"acc_title_value",30:"acc_descr",31:"acc_descr_value",32:"acc_descr_multiline_value",33:"section",35:"taskTxt",36:"taskData",37:"click",38:"callbackname",39:"callbackargs",40:"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],[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],[34,2],[34,3],[34,3],[34,4],[34,3],[34,4],[34,2],[41,2],[41,3],[41,3],[41,4],[41,3],[41,4],[41,2]],performAction:function(xe,U,Fe,Pe,je,Ie,Se){var Ce=Ie.length-1;switch(je){case 1:return Ie[Ce-1];case 2:this.$=[];break;case 3:Ie[Ce-1].push(Ie[Ce]),this.$=Ie[Ce-1];break;case 4:case 5:this.$=Ie[Ce];break;case 6:case 7:this.$=[];break;case 8:Pe.setWeekday("monday");break;case 9:Pe.setWeekday("tuesday");break;case 10:Pe.setWeekday("wednesday");break;case 11:Pe.setWeekday("thursday");break;case 12:Pe.setWeekday("friday");break;case 13:Pe.setWeekday("saturday");break;case 14:Pe.setWeekday("sunday");break;case 15:Pe.setDateFormat(Ie[Ce].substr(11)),this.$=Ie[Ce].substr(11);break;case 16:Pe.enableInclusiveEndDates(),this.$=Ie[Ce].substr(18);break;case 17:Pe.TopAxis(),this.$=Ie[Ce].substr(8);break;case 18:Pe.setAxisFormat(Ie[Ce].substr(11)),this.$=Ie[Ce].substr(11);break;case 19:Pe.setTickInterval(Ie[Ce].substr(13)),this.$=Ie[Ce].substr(13);break;case 20:Pe.setExcludes(Ie[Ce].substr(9)),this.$=Ie[Ce].substr(9);break;case 21:Pe.setIncludes(Ie[Ce].substr(9)),this.$=Ie[Ce].substr(9);break;case 22:Pe.setTodayMarker(Ie[Ce].substr(12)),this.$=Ie[Ce].substr(12);break;case 24:Pe.setDiagramTitle(Ie[Ce].substr(6)),this.$=Ie[Ce].substr(6);break;case 25:this.$=Ie[Ce].trim(),Pe.setAccTitle(this.$);break;case 26:case 27:this.$=Ie[Ce].trim(),Pe.setAccDescription(this.$);break;case 28:Pe.addSection(Ie[Ce].substr(8)),this.$=Ie[Ce].substr(8);break;case 30:Pe.addTask(Ie[Ce-1],Ie[Ce]),this.$="task";break;case 31:this.$=Ie[Ce-1],Pe.setClickEvent(Ie[Ce-1],Ie[Ce],null);break;case 32:this.$=Ie[Ce-2],Pe.setClickEvent(Ie[Ce-2],Ie[Ce-1],Ie[Ce]);break;case 33:this.$=Ie[Ce-2],Pe.setClickEvent(Ie[Ce-2],Ie[Ce-1],null),Pe.setLink(Ie[Ce-2],Ie[Ce]);break;case 34:this.$=Ie[Ce-3],Pe.setClickEvent(Ie[Ce-3],Ie[Ce-2],Ie[Ce-1]),Pe.setLink(Ie[Ce-3],Ie[Ce]);break;case 35:this.$=Ie[Ce-2],Pe.setClickEvent(Ie[Ce-2],Ie[Ce],null),Pe.setLink(Ie[Ce-2],Ie[Ce-1]);break;case 36:this.$=Ie[Ce-3],Pe.setClickEvent(Ie[Ce-3],Ie[Ce-1],Ie[Ce]),Pe.setLink(Ie[Ce-3],Ie[Ce-2]);break;case 37:this.$=Ie[Ce-1],Pe.setLink(Ie[Ce-1],Ie[Ce]);break;case 38:case 44:this.$=Ie[Ce-1]+" "+Ie[Ce];break;case 39:case 40:case 42:this.$=Ie[Ce-2]+" "+Ie[Ce-1]+" "+Ie[Ce];break;case 41:case 43:this.$=Ie[Ce-3]+" "+Ie[Ce-2]+" "+Ie[Ce-1]+" "+Ie[Ce];break}},table:[{3:1,4:[1,2]},{1:[3]},i(s,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:u,13:d,14:p,15:v,16:b,17:y,18:T,19:_,20:A,21:P,22:R,23:F,24:j,25:K,26:ee,27:ie,28:oe,30:pe,32:be,33:ae,34:23,35:ne,37:se},i(s,[2,7],{1:[2,1]}),i(s,[2,3]),{9:33,11:17,12:u,13:d,14:p,15:v,16:b,17:y,18:T,19:_,20:A,21:P,22:R,23:F,24:j,25:K,26:ee,27:ie,28:oe,30:pe,32:be,33:ae,34:23,35:ne,37:se},i(s,[2,5]),i(s,[2,6]),i(s,[2,15]),i(s,[2,16]),i(s,[2,17]),i(s,[2,18]),i(s,[2,19]),i(s,[2,20]),i(s,[2,21]),i(s,[2,22]),i(s,[2,23]),i(s,[2,24]),{29:[1,34]},{31:[1,35]},i(s,[2,27]),i(s,[2,28]),i(s,[2,29]),{36:[1,36]},i(s,[2,8]),i(s,[2,9]),i(s,[2,10]),i(s,[2,11]),i(s,[2,12]),i(s,[2,13]),i(s,[2,14]),{38:[1,37],40:[1,38]},i(s,[2,4]),i(s,[2,25]),i(s,[2,26]),i(s,[2,30]),i(s,[2,31],{39:[1,39],40:[1,40]}),i(s,[2,37],{38:[1,41]}),i(s,[2,32],{40:[1,42]}),i(s,[2,33]),i(s,[2,35],{39:[1,43]}),i(s,[2,34]),i(s,[2,36])],defaultActions:{},parseError:function(xe,U){if(U.recoverable)this.trace(xe);else{var Fe=new Error(xe);throw Fe.hash=U,Fe}},parse:function(xe){var U=this,Fe=[0],Pe=[],je=[null],Ie=[],Se=this.table,Ce="",ke=0,Ke=0,Ft=2,Ne=1,gn=Ie.slice.call(arguments,1),_t=Object.create(this.lexer),Et={yy:{}};for(var Gt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Gt)&&(Et.yy[Gt]=this.yy[Gt]);_t.setInput(xe,Et.yy),Et.yy.lexer=_t,Et.yy.parser=this,typeof _t.yylloc>"u"&&(_t.yylloc={});var ln=_t.yylloc;Ie.push(ln);var xt=_t.options&&_t.options.ranges;typeof Et.yy.parseError=="function"?this.parseError=Et.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Pt(){var zs;return zs=Pe.pop()||_t.lex()||Ne,typeof zs!="number"&&(zs instanceof Array&&(Pe=zs,zs=Pe.pop()),zs=U.symbols_[zs]||zs),zs}for(var Qe,Dt,kt,On,ht={},zr,yt,ji,xi;;){if(Dt=Fe[Fe.length-1],this.defaultActions[Dt]?kt=this.defaultActions[Dt]:((Qe===null||typeof Qe>"u")&&(Qe=Pt()),kt=Se[Dt]&&Se[Dt][Qe]),typeof kt>"u"||!kt.length||!kt[0]){var Ma="";xi=[];for(zr in Se[Dt])this.terminals_[zr]&&zr>Ft&&xi.push("'"+this.terminals_[zr]+"'");_t.showPosition?Ma="Parse error on line "+(ke+1)+`: +`+_t.showPosition()+` +Expecting `+xi.join(", ")+", got '"+(this.terminals_[Qe]||Qe)+"'":Ma="Parse error on line "+(ke+1)+": Unexpected "+(Qe==Ne?"end of input":"'"+(this.terminals_[Qe]||Qe)+"'"),this.parseError(Ma,{text:_t.match,token:this.terminals_[Qe]||Qe,line:_t.yylineno,loc:ln,expected:xi})}if(kt[0]instanceof Array&&kt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Dt+", token: "+Qe);switch(kt[0]){case 1:Fe.push(Qe),je.push(_t.yytext),Ie.push(_t.yylloc),Fe.push(kt[1]),Qe=null,Ke=_t.yyleng,Ce=_t.yytext,ke=_t.yylineno,ln=_t.yylloc;break;case 2:if(yt=this.productions_[kt[1]][1],ht.$=je[je.length-yt],ht._$={first_line:Ie[Ie.length-(yt||1)].first_line,last_line:Ie[Ie.length-1].last_line,first_column:Ie[Ie.length-(yt||1)].first_column,last_column:Ie[Ie.length-1].last_column},xt&&(ht._$.range=[Ie[Ie.length-(yt||1)].range[0],Ie[Ie.length-1].range[1]]),On=this.performAction.apply(ht,[Ce,Ke,ke,Et.yy,kt[1],je,Ie].concat(gn)),typeof On<"u")return On;yt&&(Fe=Fe.slice(0,-1*yt*2),je=je.slice(0,-1*yt),Ie=Ie.slice(0,-1*yt)),Fe.push(this.productions_[kt[1]][0]),je.push(ht.$),Ie.push(ht._$),ji=Se[Fe[Fe.length-2]][Fe[Fe.length-1]],Fe.push(ji);break;case 3:return!0}}return!0}},X=function(){var W={EOF:1,parseError:function(U,Fe){if(this.yy.parser)this.yy.parser.parseError(U,Fe);else throw new Error(U)},setInput:function(xe,U){return this.yy=U||this.yy||{},this._input=xe,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},input:function(){var xe=this._input[0];this.yytext+=xe,this.yyleng++,this.offset++,this.match+=xe,this.matched+=xe;var U=xe.match(/(?:\r\n?|\n).*/g);return U?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),xe},unput:function(xe){var U=xe.length,Fe=xe.split(/(?:\r\n?|\n)/g);this._input=xe+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-U),this.offset-=U;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),Fe.length-1&&(this.yylineno-=Fe.length-1);var je=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:Fe?(Fe.length===Pe.length?this.yylloc.first_column:0)+Pe[Pe.length-Fe.length].length-Fe[0].length:this.yylloc.first_column-U},this.options.ranges&&(this.yylloc.range=[je[0],je[0]+this.yyleng-U]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(xe){this.unput(this.match.slice(xe))},pastInput:function(){var xe=this.matched.substr(0,this.matched.length-this.match.length);return(xe.length>20?"...":"")+xe.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var xe=this.match;return xe.length<20&&(xe+=this._input.substr(0,20-xe.length)),(xe.substr(0,20)+(xe.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var xe=this.pastInput(),U=new Array(xe.length+1).join("-");return xe+this.upcomingInput()+` +`+U+"^"},test_match:function(xe,U){var Fe,Pe,je;if(this.options.backtrack_lexer&&(je={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&&(je.yylloc.range=this.yylloc.range.slice(0))),Pe=xe[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+xe[0].length},this.yytext+=xe[0],this.match+=xe[0],this.matches=xe,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(xe[0].length),this.matched+=xe[0],Fe=this.performAction.call(this,this.yy,this,U,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Fe)return Fe;if(this._backtrack){for(var Ie in je)this[Ie]=je[Ie];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var xe,U,Fe,Pe;this._more||(this.yytext="",this.match="");for(var je=this._currentRules(),Ie=0;IeU[0].length)){if(U=Fe,Pe=Ie,this.options.backtrack_lexer){if(xe=this.test_match(Fe,je[Ie]),xe!==!1)return xe;if(this._backtrack){U=!1;continue}else return!1}else if(!this.options.flex)break}return U?(xe=this.test_match(U,je[Pe]),xe!==!1?xe:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var U=this.next();return U||this.lex()},begin:function(U){this.conditionStack.push(U)},popState:function(){var U=this.conditionStack.length-1;return U>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(U){return U=this.conditionStack.length-1-Math.abs(U||0),U>=0?this.conditionStack[U]:"INITIAL"},pushState:function(U){this.begin(U)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(U,Fe,Pe,je){switch(Pe){case 0:return this.begin("open_directive"),"open_directive";case 1:return this.begin("acc_title"),28;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),30;case 4:return this.popState(),"acc_descr_value";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 40;case 17:this.begin("callbackname");break;case 18:this.popState();break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 38;case 21:this.popState();break;case 22:return 39;case 23:this.begin("click");break;case 24:this.popState();break;case 25:return 37;case 26:return 4;case 27:return 19;case 28:return 20;case 29:return 21;case 30:return 22;case 31:return 23;case 32:return 25;case 33:return 24;case 34:return 26;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"date";case 43:return 27;case 44:return"accDescription";case 45:return 33;case 46:return 35;case 47:return 36;case 48:return":";case 49:return 6;case 50:return"INVALID"}},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,/^(?:\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],inclusive:!0}}};return W}();de.lexer=X;function ge(){this.yy={}}return ge.prototype=de,de.Parser=ge,new ge}();Yme.parser=Yme;const _tn=Yme;var XUe={exports:{}};(function(i,s){(function(u,d){i.exports=d()})(Ag,function(){var u="day";return function(d,p,v){var b=function(_){return _.add(4-_.isoWeekday(),u)},y=p.prototype;y.isoWeekYear=function(){return b(this).year()},y.isoWeek=function(_){if(!this.$utils().u(_))return this.add(7*(_-this.isoWeek()),u);var A,P,R,F,j=b(this),K=(A=this.isoWeekYear(),P=this.$u,R=(P?v.utc:v)().year(A).startOf("year"),F=4-R.isoWeekday(),R.isoWeekday()>4&&(F+=7),R.add(F,u));return j.diff(K,"week")+1},y.isoWeekday=function(_){return this.$utils().u(_)?this.day()||7:this.day(this.day()%7?_:_-7)};var T=y.startOf;y.startOf=function(_,A){var P=this.$utils(),R=!!P.u(A)||A;return P.p(_)==="isoweek"?R?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):T.bind(this)(_,A)}}})})(XUe);var Atn=XUe.exports;const Ltn=hC(Atn);var QUe={exports:{}};(function(i,s){(function(u,d){i.exports=d()})(Ag,function(){var u={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"},d=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,p=/\d\d/,v=/\d\d?/,b=/\d*[^-_:/,()\s\d]+/,y={},T=function(K){return(K=+K)+(K>68?1900:2e3)},_=function(K){return function(ee){this[K]=+ee}},A=[/[+-]\d\d:?(\d\d)?|Z/,function(K){(this.zone||(this.zone={})).offset=function(ee){if(!ee||ee==="Z")return 0;var ie=ee.match(/([+-]|\d\d)/g),oe=60*ie[1]+(+ie[2]||0);return oe===0?0:ie[0]==="+"?-oe:oe}(K)}],P=function(K){var ee=y[K];return ee&&(ee.indexOf?ee:ee.s.concat(ee.f))},R=function(K,ee){var ie,oe=y.meridiem;if(oe){for(var pe=1;pe<=24;pe+=1)if(K.indexOf(oe(pe,0,ee))>-1){ie=pe>12;break}}else ie=K===(ee?"pm":"PM");return ie},F={A:[b,function(K){this.afternoon=R(K,!1)}],a:[b,function(K){this.afternoon=R(K,!0)}],S:[/\d/,function(K){this.milliseconds=100*+K}],SS:[p,function(K){this.milliseconds=10*+K}],SSS:[/\d{3}/,function(K){this.milliseconds=+K}],s:[v,_("seconds")],ss:[v,_("seconds")],m:[v,_("minutes")],mm:[v,_("minutes")],H:[v,_("hours")],h:[v,_("hours")],HH:[v,_("hours")],hh:[v,_("hours")],D:[v,_("day")],DD:[p,_("day")],Do:[b,function(K){var ee=y.ordinal,ie=K.match(/\d+/);if(this.day=ie[0],ee)for(var oe=1;oe<=31;oe+=1)ee(oe).replace(/\[|\]/g,"")===K&&(this.day=oe)}],M:[v,_("month")],MM:[p,_("month")],MMM:[b,function(K){var ee=P("months"),ie=(P("monthsShort")||ee.map(function(oe){return oe.slice(0,3)})).indexOf(K)+1;if(ie<1)throw new Error;this.month=ie%12||ie}],MMMM:[b,function(K){var ee=P("months").indexOf(K)+1;if(ee<1)throw new Error;this.month=ee%12||ee}],Y:[/[+-]?\d+/,_("year")],YY:[p,function(K){this.year=T(K)}],YYYY:[/\d{4}/,_("year")],Z:A,ZZ:A};function j(K){var ee,ie;ee=K,ie=y&&y.formats;for(var oe=(K=ee.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(X,ge,W){var xe=W&&W.toUpperCase();return ge||ie[W]||u[W]||ie[xe].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(U,Fe,Pe){return Fe||Pe.slice(1)})})).match(d),pe=oe.length,be=0;be-1)return new Date((Ie==="X"?1e3:1)*je);var Ce=j(Ie)(je),ke=Ce.year,Ke=Ce.month,Ft=Ce.day,Ne=Ce.hours,gn=Ce.minutes,_t=Ce.seconds,Et=Ce.milliseconds,Gt=Ce.zone,ln=new Date,xt=Ft||(ke||Ke?1:ln.getDate()),Pt=ke||ln.getFullYear(),Qe=0;ke&&!Ke||(Qe=Ke>0?Ke-1:ln.getMonth());var Dt=Ne||0,kt=gn||0,On=_t||0,ht=Et||0;return Gt?new Date(Date.UTC(Pt,Qe,xt,Dt,kt,On,ht+60*Gt.offset*1e3)):Se?new Date(Date.UTC(Pt,Qe,xt,Dt,kt,On,ht)):new Date(Pt,Qe,xt,Dt,kt,On,ht)}catch{return new Date("")}}(ae,de,ne),this.init(),xe&&xe!==!0&&(this.$L=this.locale(xe).$L),W&&ae!=this.format(de)&&(this.$d=new Date("")),y={}}else if(de instanceof Array)for(var U=de.length,Fe=1;Fe<=U;Fe+=1){se[1]=de[Fe-1];var Pe=ie.apply(this,se);if(Pe.isValid()){this.$d=Pe.$d,this.$L=Pe.$L,this.init();break}Fe===U&&(this.$d=new Date(""))}else pe.call(this,be)}}})})(QUe);var Mtn=QUe.exports;const Dtn=hC(Mtn);var JUe={exports:{}};(function(i,s){(function(u,d){i.exports=d()})(Ag,function(){return function(u,d){var p=d.prototype,v=p.format;p.format=function(b){var y=this,T=this.$locale();if(!this.isValid())return v.bind(this)(b);var _=this.$utils(),A=(b||"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(P){switch(P){case"Q":return Math.ceil((y.$M+1)/3);case"Do":return T.ordinal(y.$D);case"gggg":return y.weekYear();case"GGGG":return y.isoWeekYear();case"wo":return T.ordinal(y.week(),"W");case"w":case"ww":return _.s(y.week(),P==="w"?1:2,"0");case"W":case"WW":return _.s(y.isoWeek(),P==="W"?1:2,"0");case"k":case"kk":return _.s(String(y.$H===0?24:y.$H),P==="k"?1:2,"0");case"X":return Math.floor(y.$d.getTime()/1e3);case"x":return y.$d.getTime();case"z":return"["+y.offsetName()+"]";case"zzz":return"["+y.offsetName("long")+"]";default:return P}});return v.bind(this)(A)}}})})(JUe);var Itn=JUe.exports;const Otn=hC(Itn);Lg.extend(Ltn),Lg.extend(Dtn),Lg.extend(Otn);let i5="",Xme="",Qme,Jme="",FR=[],RR=[],Zme={},eve=[],uJ=[],GD="",tve="";const ZUe=["active","done","crit","milestone"];let nve=[],jR=!1,rve=!1,ive="sunday",sve=0;const Ntn=function(){eve=[],uJ=[],GD="",nve=[],lJ=0,ove=void 0,hJ=void 0,m1=[],i5="",Xme="",tve="",Qme=void 0,Jme="",FR=[],RR=[],jR=!1,rve=!1,sve=0,Zme={},Pg(),ive="sunday"},Ptn=function(i){Xme=i},Btn=function(){return Xme},Ftn=function(i){Qme=i},Rtn=function(){return Qme},jtn=function(i){Jme=i},$tn=function(){return Jme},ztn=function(i){i5=i},qtn=function(){jR=!0},Htn=function(){return jR},Vtn=function(){rve=!0},Utn=function(){return rve},Gtn=function(i){tve=i},Ktn=function(){return tve},Wtn=function(){return i5},Ytn=function(i){FR=i.toLowerCase().split(/[\s,]+/)},Xtn=function(){return FR},Qtn=function(i){RR=i.toLowerCase().split(/[\s,]+/)},Jtn=function(){return RR},Ztn=function(){return Zme},enn=function(i){GD=i,eve.push(i)},tnn=function(){return eve},nnn=function(){let i=sGe();const s=10;let u=0;for(;!i&&u=6&&u.includes("weekends")||u.includes(i.format("dddd").toLowerCase())?!0:u.includes(i.format(s.trim()))},rnn=function(i){ive=i},inn=function(){return ive},tGe=function(i,s,u,d){if(!u.length||i.manualEndTime)return;let p;i.startTime instanceof Date?p=Lg(i.startTime):p=Lg(i.startTime,s,!0),p=p.add(1,"d");let v;i.endTime instanceof Date?v=Lg(i.endTime):v=Lg(i.endTime,s,!0);const[b,y]=snn(p,v,s,u,d);i.endTime=b.toDate(),i.renderEndTime=y},snn=function(i,s,u,d,p){let v=!1,b=null;for(;i<=s;)v||(b=s.toDate()),v=eGe(i,u,d,p),v&&(s=s.add(1,"d")),i=i.add(1,"d");return[s,b]},ave=function(i,s,u){u=u.trim();const p=/^after\s+(?[\d\w- ]+)/.exec(u);if(p!==null){let b=null;for(const T of p.groups.ids.split(" ")){let _=QC(T);_!==void 0&&(!b||_.endTime>b.endTime)&&(b=_)}if(b)return b.endTime;const y=new Date;return y.setHours(0,0,0,0),y}let v=Lg(u,s.trim(),!0);if(v.isValid())return v.toDate();{Xe.debug("Invalid date:"+u),Xe.debug("With date format:"+s.trim());const b=new Date(u);if(b===void 0||isNaN(b.getTime())||b.getFullYear()<-1e4||b.getFullYear()>1e4)throw new Error("Invalid date:"+u);return b}},nGe=function(i){const s=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(i.trim());return s!==null?[Number.parseFloat(s[1]),s[2]]:[NaN,"ms"]},rGe=function(i,s,u,d=!1){u=u.trim();const v=/^until\s+(?[\d\w- ]+)/.exec(u);if(v!==null){let A=null;for(const R of v.groups.ids.split(" ")){let F=QC(R);F!==void 0&&(!A||F.startTime{window.open(u,"_self")}),Zme[d]=u)}),aGe(i,"clickable")},aGe=function(i,s){i.split(",").forEach(function(u){let d=QC(u);d!==void 0&&d.classes.push(s)})},hnn=function(i,s,u){if(qt().securityLevel!=="loose"||s===void 0)return;let d=[];if(typeof u=="string"){d=u.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let v=0;v{Ao.runFunc(s,...d)})},oGe=function(i,s){nve.push(function(){const u=document.querySelector(`[id="${i}"]`);u!==null&&u.addEventListener("click",function(){s()})},function(){const u=document.querySelector(`[id="${i}-text"]`);u!==null&&u.addEventListener("click",function(){s()})})},fnn={getConfig:()=>qt().gantt,clear:Ntn,setDateFormat:ztn,getDateFormat:Wtn,enableInclusiveEndDates:qtn,endDatesAreInclusive:Htn,enableTopAxis:Vtn,topAxisEnabled:Utn,setAxisFormat:Ptn,getAxisFormat:Btn,setTickInterval:Ftn,getTickInterval:Rtn,setTodayMarker:jtn,getTodayMarker:$tn,setAccTitle:Bg,getAccTitle:Cp,setDiagramTitle:cm,getDiagramTitle:Ap,setDisplayMode:Gtn,getDisplayMode:Ktn,setAccDescription:Sp,getAccDescription:_p,addSection:enn,getSections:tnn,getTasks:nnn,addTask:cnn,findTaskById:QC,addTaskOrg:unn,setIncludes:Ytn,getIncludes:Xtn,setExcludes:Qtn,getExcludes:Jtn,setClickEvent:function(i,s,u){i.split(",").forEach(function(d){hnn(d,s,u)}),aGe(i,"clickable")},setLink:lnn,getLinks:Ztn,bindFunctions:function(i){nve.forEach(function(s){s(i)})},parseDuration:nGe,isInvalidDate:eGe,setWeekday:rnn,getWeekday:inn};function cGe(i,s,u){let d=!0;for(;d;)d=!1,u.forEach(function(p){const v="^\\s*"+p+"\\s*$",b=new RegExp(v);i[0].match(b)&&(s[p]=!0,i.shift(1),d=!0)})}const dnn=function(){Xe.debug("Something is calling, setConf, remove the call")},uGe={monday:DF,tuesday:xFe,wednesday:kFe,thursday:yC,friday:EFe,saturday:TFe,sunday:MF},gnn=(i,s)=>{let u=[...i].map(()=>-1/0),d=[...i].sort((v,b)=>v.startTime-b.startTime||v.order-b.order),p=0;for(const v of d)for(let b=0;b=u[b]){u[b]=v.endTime,v.order=b+s,b>p&&(p=b);break}return p};let V7;const pnn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:_tn,db:fnn,renderer:{setConf:dnn,draw:function(i,s,u,d){const p=qt().gantt,v=qt().securityLevel;let b;v==="sandbox"&&(b=Ir("#i"+s));const y=Ir(v==="sandbox"?b.nodes()[0].contentDocument.body:"body"),T=v==="sandbox"?b.nodes()[0].contentDocument:document,_=T.getElementById(s);V7=_.parentElement.offsetWidth,V7===void 0&&(V7=1200),p.useWidth!==void 0&&(V7=p.useWidth);const A=d.db.getTasks();let P=[];for(const de of A)P.push(de.type);P=se(P);const R={};let F=2*p.topPadding;if(d.db.getDisplayMode()==="compact"||p.displayMode==="compact"){const de={};for(const ge of A)de[ge.section]===void 0?de[ge.section]=[ge]:de[ge.section].push(ge);let X=0;for(const ge of Object.keys(de)){const W=gnn(de[ge],X)+1;X+=W,F+=W*(p.barHeight+p.barGap),R[ge]=W}}else{F+=A.length*(p.barHeight+p.barGap);for(const de of P)R[de]=A.filter(X=>X.type===de).length}_.setAttribute("viewBox","0 0 "+V7+" "+F);const j=y.select(`[id="${s}"]`),K=fNt().domain([WAt(A,function(de){return de.startTime}),KAt(A,function(de){return de.endTime})]).rangeRound([0,V7-p.leftPadding-p.rightPadding]);function ee(de,X){const ge=de.startTime,W=X.startTime;let xe=0;return ge>W?xe=1:geke.order))].map(ke=>de.find(Ke=>Ke.order===ke));j.append("g").selectAll("rect").data(je).enter().append("rect").attr("x",0).attr("y",function(ke,Ke){return Ke=ke.order,Ke*X+ge-2}).attr("width",function(){return Fe-p.rightPadding/2}).attr("height",X).attr("class",function(ke){for(const[Ke,Ft]of P.entries())if(ke.type===Ft)return"section section"+Ke%p.numberSectionStyles;return"section section0"});const Ie=j.append("g").selectAll("rect").data(de).enter(),Se=d.db.getLinks();if(Ie.append("rect").attr("id",function(ke){return ke.id}).attr("rx",3).attr("ry",3).attr("x",function(ke){return ke.milestone?K(ke.startTime)+W+.5*(K(ke.endTime)-K(ke.startTime))-.5*xe:K(ke.startTime)+W}).attr("y",function(ke,Ke){return Ke=ke.order,Ke*X+ge}).attr("width",function(ke){return ke.milestone?xe:K(ke.renderEndTime||ke.endTime)-K(ke.startTime)}).attr("height",xe).attr("transform-origin",function(ke,Ke){return Ke=ke.order,(K(ke.startTime)+W+.5*(K(ke.endTime)-K(ke.startTime))).toString()+"px "+(Ke*X+ge+.5*xe).toString()+"px"}).attr("class",function(ke){const Ke="task";let Ft="";ke.classes.length>0&&(Ft=ke.classes.join(" "));let Ne=0;for(const[_t,Et]of P.entries())ke.type===Et&&(Ne=_t%p.numberSectionStyles);let gn="";return ke.active?ke.crit?gn+=" activeCrit":gn=" active":ke.done?ke.crit?gn=" doneCrit":gn=" done":ke.crit&&(gn+=" crit"),gn.length===0&&(gn=" task"),ke.milestone&&(gn=" milestone "+gn),gn+=Ne,gn+=" "+Ft,Ke+gn}),Ie.append("text").attr("id",function(ke){return ke.id+"-text"}).text(function(ke){return ke.task}).attr("font-size",p.fontSize).attr("x",function(ke){let Ke=K(ke.startTime),Ft=K(ke.renderEndTime||ke.endTime);ke.milestone&&(Ke+=.5*(K(ke.endTime)-K(ke.startTime))-.5*xe),ke.milestone&&(Ft=Ke+xe);const Ne=this.getBBox().width;return Ne>Ft-Ke?Ft+Ne+1.5*p.leftPadding>Fe?Ke+W-5:Ft+W+5:(Ft-Ke)/2+Ke+W}).attr("y",function(ke,Ke){return Ke=ke.order,Ke*X+p.barHeight/2+(p.fontSize/2-2)+ge}).attr("text-height",xe).attr("class",function(ke){const Ke=K(ke.startTime);let Ft=K(ke.endTime);ke.milestone&&(Ft=Ke+xe);const Ne=this.getBBox().width;let gn="";ke.classes.length>0&&(gn=ke.classes.join(" "));let _t=0;for(const[Gt,ln]of P.entries())ke.type===ln&&(_t=Gt%p.numberSectionStyles);let Et="";return ke.active&&(ke.crit?Et="activeCritText"+_t:Et="activeText"+_t),ke.done?ke.crit?Et=Et+" doneCritText"+_t:Et=Et+" doneText"+_t:ke.crit&&(Et=Et+" critText"+_t),ke.milestone&&(Et+=" milestoneText"),Ne>Ft-Ke?Ft+Ne+1.5*p.leftPadding>Fe?gn+" taskTextOutsideLeft taskTextOutside"+_t+" "+Et:gn+" taskTextOutsideRight taskTextOutside"+_t+" "+Et+" width-"+Ne:gn+" taskText taskText"+_t+" "+Et+" width-"+Ne}),qt().securityLevel==="sandbox"){let ke;ke=Ir("#i"+s);const Ke=ke.nodes()[0].contentDocument;Ie.filter(function(Ft){return Se[Ft.id]!==void 0}).each(function(Ft){var Ne=Ke.querySelector("#"+Ft.id),gn=Ke.querySelector("#"+Ft.id+"-text");const _t=Ne.parentNode;var Et=Ke.createElement("a");Et.setAttribute("xlink:href",Se[Ft.id]),Et.setAttribute("target","_top"),_t.appendChild(Et),Et.appendChild(Ne),Et.appendChild(gn)})}}function pe(de,X,ge,W,xe,U,Fe,Pe){if(Fe.length===0&&Pe.length===0)return;let je,Ie;for(const{startTime:Ne,endTime:gn}of U)(je===void 0||NeIe)&&(Ie=gn);if(!je||!Ie)return;if(Lg(Ie).diff(Lg(je),"year")>5){Xe.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");return}const Se=d.db.getDateFormat(),Ce=[];let ke=null,Ke=Lg(je);for(;Ke.valueOf()<=Ie;)d.db.isInvalidDate(Ke,Se,Fe,Pe)?ke?ke.end=Ke:ke={start:Ke,end:Ke}:ke&&(Ce.push(ke),ke=null),Ke=Ke.add(1,"d");j.append("g").selectAll("rect").data(Ce).enter().append("rect").attr("id",function(Ne){return"exclude-"+Ne.start.format("YYYY-MM-DD")}).attr("x",function(Ne){return K(Ne.start)+ge}).attr("y",p.gridLineStartPadding).attr("width",function(Ne){const gn=Ne.end.add(1,"day");return K(gn)-K(Ne.start)}).attr("height",xe-X-p.gridLineStartPadding).attr("transform-origin",function(Ne,gn){return(K(Ne.start)+ge+.5*(K(Ne.end)-K(Ne.start))).toString()+"px "+(gn*de+.5*xe).toString()+"px"}).attr("class","exclude-range")}function be(de,X,ge,W){let xe=rLt(K).tickSize(-W+X+p.gridLineStartPadding).tickFormat(sX(d.db.getAxisFormat()||p.axisFormat||"%Y-%m-%d"));const Fe=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(d.db.getTickInterval()||p.tickInterval);if(Fe!==null){const Pe=Fe[1],je=Fe[2],Ie=d.db.getWeekday()||p.weekday;switch(je){case"millisecond":xe.ticks(aD.every(Pe));break;case"second":xe.ticks(b9.every(Pe));break;case"minute":xe.ticks(AF.every(Pe));break;case"hour":xe.ticks(LF.every(Pe));break;case"day":xe.ticks(vC.every(Pe));break;case"week":xe.ticks(uGe[Ie].every(Pe));break;case"month":xe.ticks(IF.every(Pe));break}}if(j.append("g").attr("class","grid").attr("transform","translate("+de+", "+(W-50)+")").call(xe).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),d.db.topAxisEnabled()||p.topAxis){let Pe=nLt(K).tickSize(-W+X+p.gridLineStartPadding).tickFormat(sX(d.db.getAxisFormat()||p.axisFormat||"%Y-%m-%d"));if(Fe!==null){const je=Fe[1],Ie=Fe[2],Se=d.db.getWeekday()||p.weekday;switch(Ie){case"millisecond":Pe.ticks(aD.every(je));break;case"second":Pe.ticks(b9.every(je));break;case"minute":Pe.ticks(AF.every(je));break;case"hour":Pe.ticks(LF.every(je));break;case"day":Pe.ticks(vC.every(je));break;case"week":Pe.ticks(uGe[Se].every(je));break;case"month":Pe.ticks(IF.every(je));break}}j.append("g").attr("class","grid").attr("transform","translate("+de+", "+X+")").call(Pe).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}function ae(de,X){let ge=0;const W=Object.keys(R).map(xe=>[xe,R[xe]]);j.append("g").selectAll("text").data(W).enter().append(function(xe){const U=xe[0].split(ci.lineBreakRegex),Fe=-(U.length-1)/2,Pe=T.createElementNS("http://www.w3.org/2000/svg","text");Pe.setAttribute("dy",Fe+"em");for(const[je,Ie]of U.entries()){const Se=T.createElementNS("http://www.w3.org/2000/svg","tspan");Se.setAttribute("alignment-baseline","central"),Se.setAttribute("x","10"),je>0&&Se.setAttribute("dy","1em"),Se.textContent=Ie,Pe.appendChild(Se)}return Pe}).attr("x",10).attr("y",function(xe,U){if(U>0)for(let Fe=0;Fe` + .mermaid-main-font { + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + .exclude-range { + fill: ${i.excludeBkgColor}; + } + + .section { + stroke: none; + opacity: 0.2; + } + + .section0 { + fill: ${i.sectionBkgColor}; + } + + .section2 { + fill: ${i.sectionBkgColor2}; + } + + .section1, + .section3 { + fill: ${i.altSectionBkgColor}; + opacity: 0.2; + } + + .sectionTitle0 { + fill: ${i.titleColor}; + } + + .sectionTitle1 { + fill: ${i.titleColor}; + } + + .sectionTitle2 { + fill: ${i.titleColor}; + } + + .sectionTitle3 { + fill: ${i.titleColor}; + } + + .sectionTitle { + text-anchor: start; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + + /* Grid and axis */ + + .grid .tick { + stroke: ${i.gridColor}; + opacity: 0.8; + shape-rendering: crispEdges; + } + + .grid .tick text { + font-family: ${i.fontFamily}; + fill: ${i.textColor}; + } + + .grid path { + stroke-width: 0; + } + + + /* Today line */ + + .today { + fill: none; + stroke: ${i.todayLineColor}; + stroke-width: 2px; + } + + + /* Task styling */ + + /* Default task */ + + .task { + stroke-width: 2; + } + + .taskText { + text-anchor: middle; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + .taskTextOutsideRight { + fill: ${i.taskTextDarkColor}; + text-anchor: start; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + .taskTextOutsideLeft { + fill: ${i.taskTextDarkColor}; + text-anchor: end; + } + + + /* Special case clickable */ + + .task.clickable { + cursor: pointer; + } + + .taskText.clickable { + cursor: pointer; + fill: ${i.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideLeft.clickable { + cursor: pointer; + fill: ${i.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideRight.clickable { + cursor: pointer; + fill: ${i.taskTextClickableColor} !important; + font-weight: bold; + } + + + /* Specific task settings for the sections*/ + + .taskText0, + .taskText1, + .taskText2, + .taskText3 { + fill: ${i.taskTextColor}; + } + + .task0, + .task1, + .task2, + .task3 { + fill: ${i.taskBkgColor}; + stroke: ${i.taskBorderColor}; + } + + .taskTextOutside0, + .taskTextOutside2 + { + fill: ${i.taskTextOutsideColor}; + } + + .taskTextOutside1, + .taskTextOutside3 { + fill: ${i.taskTextOutsideColor}; + } + + + /* Active task */ + + .active0, + .active1, + .active2, + .active3 { + fill: ${i.activeTaskBkgColor}; + stroke: ${i.activeTaskBorderColor}; + } + + .activeText0, + .activeText1, + .activeText2, + .activeText3 { + fill: ${i.taskTextDarkColor} !important; + } + + + /* Completed task */ + + .done0, + .done1, + .done2, + .done3 { + stroke: ${i.doneTaskBorderColor}; + fill: ${i.doneTaskBkgColor}; + stroke-width: 2; + } + + .doneText0, + .doneText1, + .doneText2, + .doneText3 { + fill: ${i.taskTextDarkColor} !important; + } + + + /* Tasks on the critical line */ + + .crit0, + .crit1, + .crit2, + .crit3 { + stroke: ${i.critBorderColor}; + fill: ${i.critBkgColor}; + stroke-width: 2; + } + + .activeCrit0, + .activeCrit1, + .activeCrit2, + .activeCrit3 { + stroke: ${i.critBorderColor}; + fill: ${i.activeTaskBkgColor}; + stroke-width: 2; + } + + .doneCrit0, + .doneCrit1, + .doneCrit2, + .doneCrit3 { + stroke: ${i.critBorderColor}; + fill: ${i.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: ${i.taskTextDarkColor} !important; + } + + .activeCritText0, + .activeCritText1, + .activeCritText2, + .activeCritText3 { + fill: ${i.taskTextDarkColor} !important; + } + + .titleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.titleColor||i.textColor}; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } +`}},Symbol.toStringTag,{value:"Module"}));var cve=function(){var i=function(v,b,y,T){for(y=y||{},T=v.length;T--;y[v[T]]=b);return y},s=[6,9,10],u={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(b,y,T,_,A,P,R){switch(P.length-1,A){case 1:return _;case 4:break;case 6:_.setInfo(!0);break}},table:[{3:1,4:[1,2]},{1:[3]},i(s,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},i(s,[2,3]),i(s,[2,4]),i(s,[2,5]),i(s,[2,6])],defaultActions:{4:[2,1]},parseError:function(b,y){if(y.recoverable)this.trace(b);else{var T=new Error(b);throw T.hash=y,T}},parse:function(b){var y=this,T=[0],_=[],A=[null],P=[],R=this.table,F="",j=0,K=0,ee=2,ie=1,oe=P.slice.call(arguments,1),pe=Object.create(this.lexer),be={yy:{}};for(var ae in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ae)&&(be.yy[ae]=this.yy[ae]);pe.setInput(b,be.yy),be.yy.lexer=pe,be.yy.parser=this,typeof pe.yylloc>"u"&&(pe.yylloc={});var ne=pe.yylloc;P.push(ne);var se=pe.options&&pe.options.ranges;typeof be.yy.parseError=="function"?this.parseError=be.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function de(){var Ce;return Ce=_.pop()||pe.lex()||ie,typeof Ce!="number"&&(Ce instanceof Array&&(_=Ce,Ce=_.pop()),Ce=y.symbols_[Ce]||Ce),Ce}for(var X,ge,W,xe,U={},Fe,Pe,je,Ie;;){if(ge=T[T.length-1],this.defaultActions[ge]?W=this.defaultActions[ge]:((X===null||typeof X>"u")&&(X=de()),W=R[ge]&&R[ge][X]),typeof W>"u"||!W.length||!W[0]){var Se="";Ie=[];for(Fe in R[ge])this.terminals_[Fe]&&Fe>ee&&Ie.push("'"+this.terminals_[Fe]+"'");pe.showPosition?Se="Parse error on line "+(j+1)+`: +`+pe.showPosition()+` +Expecting `+Ie.join(", ")+", got '"+(this.terminals_[X]||X)+"'":Se="Parse error on line "+(j+1)+": Unexpected "+(X==ie?"end of input":"'"+(this.terminals_[X]||X)+"'"),this.parseError(Se,{text:pe.match,token:this.terminals_[X]||X,line:pe.yylineno,loc:ne,expected:Ie})}if(W[0]instanceof Array&&W.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ge+", token: "+X);switch(W[0]){case 1:T.push(X),A.push(pe.yytext),P.push(pe.yylloc),T.push(W[1]),X=null,K=pe.yyleng,F=pe.yytext,j=pe.yylineno,ne=pe.yylloc;break;case 2:if(Pe=this.productions_[W[1]][1],U.$=A[A.length-Pe],U._$={first_line:P[P.length-(Pe||1)].first_line,last_line:P[P.length-1].last_line,first_column:P[P.length-(Pe||1)].first_column,last_column:P[P.length-1].last_column},se&&(U._$.range=[P[P.length-(Pe||1)].range[0],P[P.length-1].range[1]]),xe=this.performAction.apply(U,[F,K,j,be.yy,W[1],A,P].concat(oe)),typeof xe<"u")return xe;Pe&&(T=T.slice(0,-1*Pe*2),A=A.slice(0,-1*Pe),P=P.slice(0,-1*Pe)),T.push(this.productions_[W[1]][0]),A.push(U.$),P.push(U._$),je=R[T[T.length-2]][T[T.length-1]],T.push(je);break;case 3:return!0}}return!0}},d=function(){var v={EOF:1,parseError:function(y,T){if(this.yy.parser)this.yy.parser.parseError(y,T);else throw new Error(y)},setInput:function(b,y){return this.yy=y||this.yy||{},this._input=b,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},input:function(){var b=this._input[0];this.yytext+=b,this.yyleng++,this.offset++,this.match+=b,this.matched+=b;var y=b.match(/(?:\r\n?|\n).*/g);return y?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),b},unput:function(b){var y=b.length,T=b.split(/(?:\r\n?|\n)/g);this._input=b+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-y),this.offset-=y;var _=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),T.length-1&&(this.yylineno-=T.length-1);var A=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:T?(T.length===_.length?this.yylloc.first_column:0)+_[_.length-T.length].length-T[0].length:this.yylloc.first_column-y},this.options.ranges&&(this.yylloc.range=[A[0],A[0]+this.yyleng-y]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(b){this.unput(this.match.slice(b))},pastInput:function(){var b=this.matched.substr(0,this.matched.length-this.match.length);return(b.length>20?"...":"")+b.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var b=this.match;return b.length<20&&(b+=this._input.substr(0,20-b.length)),(b.substr(0,20)+(b.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var b=this.pastInput(),y=new Array(b.length+1).join("-");return b+this.upcomingInput()+` +`+y+"^"},test_match:function(b,y){var T,_,A;if(this.options.backtrack_lexer&&(A={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&&(A.yylloc.range=this.yylloc.range.slice(0))),_=b[0].match(/(?:\r\n?|\n).*/g),_&&(this.yylineno+=_.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:_?_[_.length-1].length-_[_.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,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(b[0].length),this.matched+=b[0],T=this.performAction.call(this,this.yy,this,y,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),T)return T;if(this._backtrack){for(var P in A)this[P]=A[P];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var b,y,T,_;this._more||(this.yytext="",this.match="");for(var A=this._currentRules(),P=0;Py[0].length)){if(y=T,_=P,this.options.backtrack_lexer){if(b=this.test_match(T,A[P]),b!==!1)return b;if(this._backtrack){y=!1;continue}else return!1}else if(!this.options.flex)break}return y?(b=this.test_match(y,A[_]),b!==!1?b:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var y=this.next();return y||this.lex()},begin:function(y){this.conditionStack.push(y)},popState:function(){var y=this.conditionStack.length-1;return y>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(y){return y=this.conditionStack.length-1-Math.abs(y||0),y>=0?this.conditionStack[y]:"INITIAL"},pushState:function(y){this.begin(y)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(y,T,_,A){switch(_){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};return v}();u.lexer=d;function p(){this.yy={}}return p.prototype=u,u.Parser=p,new p}();cve.parser=cve;const bnn=cve,lGe={info:!1};let uve=lGe.info;const mnn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:bnn,db:{clear:()=>{uve=lGe.info},setInfo:i=>{uve=i},getInfo:()=>uve},renderer:{draw:(i,s,u)=>{Xe.debug(`rendering info diagram +`+i);const d=rR(s);Ng(d,100,400,!0),d.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${u}`)}}}},Symbol.toStringTag,{value:"Module"}));var lve=function(){var i=function(pe,be,ae,ne){for(ae=ae||{},ne=pe.length;ne--;ae[pe[ne]]=be);return ae},s=[1,3],u=[1,4],d=[1,5],p=[1,6],v=[1,10,12,14,16,18,19,20,21,22],b=[2,4],y=[1,5,10,12,14,16,18,19,20,21,22],T=[20,21,22],_=[2,7],A=[1,12],P=[1,13],R=[1,14],F=[1,15],j=[1,16],K=[1,17],ee={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,PIE:5,document:6,showData:7,line:8,statement:9,txt:10,value:11,title:12,title_value:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,section:19,NEWLINE:20,";":21,EOF:22,$accept:0,$end:1},terminals_:{2:"error",5:"PIE",7:"showData",10:"txt",11:"value",12:"title",13:"title_value",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"section",20:"NEWLINE",21:";",22:"EOF"},productions_:[0,[3,2],[3,2],[3,3],[6,0],[6,2],[8,2],[9,0],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[4,1],[4,1],[4,1]],performAction:function(be,ae,ne,se,de,X,ge){var W=X.length-1;switch(de){case 3:se.setShowData(!0);break;case 6:this.$=X[W-1];break;case 8:se.addSection(X[W-1],se.cleanupValue(X[W]));break;case 9:this.$=X[W].trim(),se.setDiagramTitle(this.$);break;case 10:this.$=X[W].trim(),se.setAccTitle(this.$);break;case 11:case 12:this.$=X[W].trim(),se.setAccDescription(this.$);break;case 13:se.addSection(X[W].substr(8)),this.$=X[W].substr(8);break}},table:[{3:1,4:2,5:s,20:u,21:d,22:p},{1:[3]},{3:7,4:2,5:s,20:u,21:d,22:p},i(v,b,{6:8,7:[1,9]}),i(y,[2,14]),i(y,[2,15]),i(y,[2,16]),{1:[2,1]},i(T,_,{8:10,9:11,1:[2,2],10:A,12:P,14:R,16:F,18:j,19:K}),i(v,b,{6:18}),i(v,[2,5]),{4:19,20:u,21:d,22:p},{11:[1,20]},{13:[1,21]},{15:[1,22]},{17:[1,23]},i(T,[2,12]),i(T,[2,13]),i(T,_,{8:10,9:11,1:[2,3],10:A,12:P,14:R,16:F,18:j,19:K}),i(v,[2,6]),i(T,[2,8]),i(T,[2,9]),i(T,[2,10]),i(T,[2,11])],defaultActions:{7:[2,1]},parseError:function(be,ae){if(ae.recoverable)this.trace(be);else{var ne=new Error(be);throw ne.hash=ae,ne}},parse:function(be){var ae=this,ne=[0],se=[],de=[null],X=[],ge=this.table,W="",xe=0,U=0,Fe=2,Pe=1,je=X.slice.call(arguments,1),Ie=Object.create(this.lexer),Se={yy:{}};for(var Ce in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ce)&&(Se.yy[Ce]=this.yy[Ce]);Ie.setInput(be,Se.yy),Se.yy.lexer=Ie,Se.yy.parser=this,typeof Ie.yylloc>"u"&&(Ie.yylloc={});var ke=Ie.yylloc;X.push(ke);var Ke=Ie.options&&Ie.options.ranges;typeof Se.yy.parseError=="function"?this.parseError=Se.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ft(){var kt;return kt=se.pop()||Ie.lex()||Pe,typeof kt!="number"&&(kt instanceof Array&&(se=kt,kt=se.pop()),kt=ae.symbols_[kt]||kt),kt}for(var Ne,gn,_t,Et,Gt={},ln,xt,Pt,Qe;;){if(gn=ne[ne.length-1],this.defaultActions[gn]?_t=this.defaultActions[gn]:((Ne===null||typeof Ne>"u")&&(Ne=Ft()),_t=ge[gn]&&ge[gn][Ne]),typeof _t>"u"||!_t.length||!_t[0]){var Dt="";Qe=[];for(ln in ge[gn])this.terminals_[ln]&&ln>Fe&&Qe.push("'"+this.terminals_[ln]+"'");Ie.showPosition?Dt="Parse error on line "+(xe+1)+`: +`+Ie.showPosition()+` +Expecting `+Qe.join(", ")+", got '"+(this.terminals_[Ne]||Ne)+"'":Dt="Parse error on line "+(xe+1)+": Unexpected "+(Ne==Pe?"end of input":"'"+(this.terminals_[Ne]||Ne)+"'"),this.parseError(Dt,{text:Ie.match,token:this.terminals_[Ne]||Ne,line:Ie.yylineno,loc:ke,expected:Qe})}if(_t[0]instanceof Array&&_t.length>1)throw new Error("Parse Error: multiple actions possible at state: "+gn+", token: "+Ne);switch(_t[0]){case 1:ne.push(Ne),de.push(Ie.yytext),X.push(Ie.yylloc),ne.push(_t[1]),Ne=null,U=Ie.yyleng,W=Ie.yytext,xe=Ie.yylineno,ke=Ie.yylloc;break;case 2:if(xt=this.productions_[_t[1]][1],Gt.$=de[de.length-xt],Gt._$={first_line:X[X.length-(xt||1)].first_line,last_line:X[X.length-1].last_line,first_column:X[X.length-(xt||1)].first_column,last_column:X[X.length-1].last_column},Ke&&(Gt._$.range=[X[X.length-(xt||1)].range[0],X[X.length-1].range[1]]),Et=this.performAction.apply(Gt,[W,U,xe,Se.yy,_t[1],de,X].concat(je)),typeof Et<"u")return Et;xt&&(ne=ne.slice(0,-1*xt*2),de=de.slice(0,-1*xt),X=X.slice(0,-1*xt)),ne.push(this.productions_[_t[1]][0]),de.push(Gt.$),X.push(Gt._$),Pt=ge[ne[ne.length-2]][ne[ne.length-1]],ne.push(Pt);break;case 3:return!0}}return!0}},ie=function(){var pe={EOF:1,parseError:function(ae,ne){if(this.yy.parser)this.yy.parser.parseError(ae,ne);else throw new Error(ae)},setInput:function(be,ae){return this.yy=ae||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},input:function(){var be=this._input[0];this.yytext+=be,this.yyleng++,this.offset++,this.match+=be,this.matched+=be;var ae=be.match(/(?:\r\n?|\n).*/g);return ae?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),be},unput:function(be){var ae=be.length,ne=be.split(/(?:\r\n?|\n)/g);this._input=be+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-ae),this.offset-=ae;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),ne.length-1&&(this.yylineno-=ne.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:ne?(ne.length===se.length?this.yylloc.first_column:0)+se[se.length-ne.length].length-ne[0].length:this.yylloc.first_column-ae},this.options.ranges&&(this.yylloc.range=[de[0],de[0]+this.yyleng-ae]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(be){this.unput(this.match.slice(be))},pastInput:function(){var be=this.matched.substr(0,this.matched.length-this.match.length);return(be.length>20?"...":"")+be.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var be=this.pastInput(),ae=new Array(be.length+1).join("-");return be+this.upcomingInput()+` +`+ae+"^"},test_match:function(be,ae){var ne,se,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))),se=be[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+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],ne=this.performAction.call(this,this.yy,this,ae,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ne)return ne;if(this._backtrack){for(var X in de)this[X]=de[X];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var be,ae,ne,se;this._more||(this.yytext="",this.match="");for(var de=this._currentRules(),X=0;Xae[0].length)){if(ae=ne,se=X,this.options.backtrack_lexer){if(be=this.test_match(ne,de[X]),be!==!1)return be;if(this._backtrack){ae=!1;continue}else return!1}else if(!this.options.flex)break}return ae?(be=this.test_match(ae,de[se]),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})},lex:function(){var ae=this.next();return ae||this.lex()},begin:function(ae){this.conditionStack.push(ae)},popState:function(){var ae=this.conditionStack.length-1;return ae>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(ae){return ae=this.conditionStack.length-1-Math.abs(ae||0),ae>=0?this.conditionStack[ae]:"INITIAL"},pushState:function(ae){this.begin(ae)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(ae,ne,se,de){switch(se){case 0:break;case 1:break;case 2:return 20;case 3:break;case 4:break;case 5:return this.begin("title"),12;case 6:return this.popState(),"title_value";case 7:return this.begin("acc_title"),14;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),16;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:this.begin("string");break;case 15:this.popState();break;case 16:return"txt";case 17:return 5;case 18:return 7;case 19:return"value";case 20:return 22}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/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,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[6],inclusive:!1},string:{rules:[15,16],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,7,9,11,14,17,18,19,20],inclusive:!0}}};return pe}();ee.lexer=ie;function oe(){this.yy={}}return oe.prototype=ee,ee.Parser=oe,new oe}();lve.parser=lve;const vnn=lve,hGe=sh.pie,fJ={sections:{},showData:!1,config:hGe};let dJ=fJ.sections,hve=fJ.showData;const wnn=structuredClone(hGe),ynn={getConfig:()=>structuredClone(wnn),clear:()=>{dJ=structuredClone(fJ.sections),hve=fJ.showData,Pg()},setDiagramTitle:cm,getDiagramTitle:Ap,setAccTitle:Bg,getAccTitle:Cp,setAccDescription:Sp,getAccDescription:_p,addSection:(i,s)=>{i=Yf(i,qt()),dJ[i]===void 0&&(dJ[i]=s,Xe.debug(`added new section: ${i}, with value: ${s}`))},getSections:()=>dJ,cleanupValue:i=>(i.substring(0,1)===":"&&(i=i.substring(1).trim()),Number(i.trim())),setShowData:i=>{hve=i},getShowData:()=>hve},xnn=i=>` + .pieCircle{ + stroke: ${i.pieStrokeColor}; + stroke-width : ${i.pieStrokeWidth}; + opacity : ${i.pieOpacity}; + } + .pieOuterCircle{ + stroke: ${i.pieOuterStrokeColor}; + stroke-width: ${i.pieOuterStrokeWidth}; + fill: none; + } + .pieTitleText { + text-anchor: middle; + font-size: ${i.pieTitleTextSize}; + fill: ${i.pieTitleTextColor}; + font-family: ${i.fontFamily}; + } + .slice { + font-family: ${i.fontFamily}; + fill: ${i.pieSectionTextColor}; + font-size:${i.pieSectionTextSize}; + // fill: white; + } + .legend text { + fill: ${i.pieLegendTextColor}; + font-family: ${i.fontFamily}; + font-size: ${i.pieLegendTextSize}; + } +`,knn=i=>{const s=Object.entries(i).map(d=>({label:d[0],value:d[1]})).sort((d,p)=>p.value-d.value);return SNt().value(d=>d.value)(s)},Enn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:vnn,db:ynn,renderer:{draw:(i,s,u,d)=>{Xe.debug(`rendering pie chart +`+i);const p=d.db,v=qt(),b=JF(p.getConfig(),v.pie),y=40,T=18,_=4,A=450,P=A,R=rR(s),F=R.append("g"),j=p.getSections();F.attr("transform","translate("+P/2+","+A/2+")");const{themeVariables:K}=v;let[ee]=NC(K.pieOuterStrokeWidth);ee??(ee=2);const ie=b.textPosition,oe=Math.min(P,A)/2-y,pe=lD().innerRadius(0).outerRadius(oe),be=lD().innerRadius(oe*ie).outerRadius(oe*ie);F.append("circle").attr("cx",0).attr("cy",0).attr("r",oe+ee/2).attr("class","pieOuterCircle");const ae=knn(j),ne=[K.pie1,K.pie2,K.pie3,K.pie4,K.pie5,K.pie6,K.pie7,K.pie8,K.pie9,K.pie10,K.pie11,K.pie12],se=_F(ne);F.selectAll("mySlices").data(ae).enter().append("path").attr("d",pe).attr("fill",xe=>se(xe.data.label)).attr("class","pieCircle");let de=0;Object.keys(j).forEach(xe=>{de+=j[xe]}),F.selectAll("mySlices").data(ae).enter().append("text").text(xe=>(xe.data.value/de*100).toFixed(0)+"%").attr("transform",xe=>"translate("+be.centroid(xe)+")").style("text-anchor","middle").attr("class","slice"),F.append("text").text(p.getDiagramTitle()).attr("x",0).attr("y",-(A-50)/2).attr("class","pieTitleText");const X=F.selectAll(".legend").data(se.domain()).enter().append("g").attr("class","legend").attr("transform",(xe,U)=>{const Fe=T+_,Pe=Fe*se.domain().length/2,je=12*T,Ie=U*Fe-Pe;return"translate("+je+","+Ie+")"});X.append("rect").attr("width",T).attr("height",T).style("fill",se).style("stroke",se),X.data(ae).append("text").attr("x",T+_).attr("y",T-_).text(xe=>{const{label:U,value:Fe}=xe.data;return p.getShowData()?`${U} [${Fe}]`:U});const ge=Math.max(...X.selectAll("text").nodes().map(xe=>(xe==null?void 0:xe.getBoundingClientRect().width)??0)),W=P+y+T+_+ge;R.attr("viewBox",`0 0 ${W} ${A}`),Ng(R,A,W,b.useMaxWidth)}},styles:xnn}},Symbol.toStringTag,{value:"Module"}));var fve=function(){var i=function(_t,Et,Gt,ln){for(Gt=Gt||{},ln=_t.length;ln--;Gt[_t[ln]]=Et);return Gt},s=[1,3],u=[1,4],d=[1,5],p=[1,6],v=[1,7],b=[1,5,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],y=[1,5,6,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],T=[32,33,34],_=[2,7],A=[1,13],P=[1,17],R=[1,18],F=[1,19],j=[1,20],K=[1,21],ee=[1,22],ie=[1,23],oe=[1,24],pe=[1,25],be=[1,26],ae=[1,27],ne=[1,30],se=[1,31],de=[1,32],X=[1,33],ge=[1,34],W=[1,35],xe=[1,36],U=[1,37],Fe=[1,38],Pe=[1,39],je=[1,40],Ie=[1,41],Se=[1,42],Ce=[1,57],ke=[1,58],Ke=[5,22,26,32,33,34,40,41,42,43,44,45,46,47,48,49,50,51],Ft={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,QUADRANT:6,document:7,line:8,statement:9,axisDetails:10,quadrantDetails:11,points:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,text:21,point_start:22,point_x:23,point_y:24,"X-AXIS":25,"AXIS-TEXT-DELIMITER":26,"Y-AXIS":27,QUADRANT_1:28,QUADRANT_2:29,QUADRANT_3:30,QUADRANT_4:31,NEWLINE:32,SEMI:33,EOF:34,alphaNumToken:35,textNoTagsToken:36,STR:37,MD_STR:38,alphaNum:39,PUNCTUATION:40,AMP:41,NUM:42,ALPHA:43,COMMA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,UNDERSCORE:50,MINUS:51,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",6:"QUADRANT",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",22:"point_start",23:"point_x",24:"point_y",25:"X-AXIS",26:"AXIS-TEXT-DELIMITER",27:"Y-AXIS",28:"QUADRANT_1",29:"QUADRANT_2",30:"QUADRANT_3",31:"QUADRANT_4",32:"NEWLINE",33:"SEMI",34:"EOF",37:"STR",38:"MD_STR",40:"PUNCTUATION",41:"AMP",42:"NUM",43:"ALPHA",44:"COMMA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"UNDERSCORE",51:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[9,0],[9,2],[9,1],[9,1],[9,1],[9,2],[9,2],[9,2],[9,1],[9,1],[12,4],[10,4],[10,3],[10,2],[10,4],[10,3],[10,2],[11,2],[11,2],[11,2],[11,2],[4,1],[4,1],[4,1],[21,1],[21,2],[21,1],[21,1],[39,1],[39,2],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[36,1],[36,1],[36,1]],performAction:function(Et,Gt,ln,xt,Pt,Qe,Dt){var kt=Qe.length-1;switch(Pt){case 12:this.$=Qe[kt].trim(),xt.setDiagramTitle(this.$);break;case 13:this.$=Qe[kt].trim(),xt.setAccTitle(this.$);break;case 14:case 15:this.$=Qe[kt].trim(),xt.setAccDescription(this.$);break;case 16:xt.addSection(Qe[kt].substr(8)),this.$=Qe[kt].substr(8);break;case 17:xt.addPoint(Qe[kt-3],Qe[kt-1],Qe[kt]);break;case 18:xt.setXAxisLeftText(Qe[kt-2]),xt.setXAxisRightText(Qe[kt]);break;case 19:Qe[kt-1].text+=" ⟶ ",xt.setXAxisLeftText(Qe[kt-1]);break;case 20:xt.setXAxisLeftText(Qe[kt]);break;case 21:xt.setYAxisBottomText(Qe[kt-2]),xt.setYAxisTopText(Qe[kt]);break;case 22:Qe[kt-1].text+=" ⟶ ",xt.setYAxisBottomText(Qe[kt-1]);break;case 23:xt.setYAxisBottomText(Qe[kt]);break;case 24:xt.setQuadrant1Text(Qe[kt]);break;case 25:xt.setQuadrant2Text(Qe[kt]);break;case 26:xt.setQuadrant3Text(Qe[kt]);break;case 27:xt.setQuadrant4Text(Qe[kt]);break;case 31:this.$={text:Qe[kt],type:"text"};break;case 32:this.$={text:Qe[kt-1].text+""+Qe[kt],type:Qe[kt-1].type};break;case 33:this.$={text:Qe[kt],type:"text"};break;case 34:this.$={text:Qe[kt],type:"markdown"};break;case 35:this.$=Qe[kt];break;case 36:this.$=Qe[kt-1]+""+Qe[kt];break}},table:[{3:1,4:2,5:s,6:u,32:d,33:p,34:v},{1:[3]},{3:8,4:2,5:s,6:u,32:d,33:p,34:v},{3:9,4:2,5:s,6:u,32:d,33:p,34:v},i(b,[2,4],{7:10}),i(y,[2,28]),i(y,[2,29]),i(y,[2,30]),{1:[2,1]},{1:[2,2]},i(T,_,{8:11,9:12,10:14,11:15,12:16,21:28,35:29,1:[2,3],5:A,13:P,15:R,17:F,19:j,20:K,25:ee,27:ie,28:oe,29:pe,30:be,31:ae,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se}),i(b,[2,5]),{4:43,32:d,33:p,34:v},i(T,_,{10:14,11:15,12:16,21:28,35:29,9:44,5:A,13:P,15:R,17:F,19:j,20:K,25:ee,27:ie,28:oe,29:pe,30:be,31:ae,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se}),i(T,[2,9]),i(T,[2,10]),i(T,[2,11]),{14:[1,45]},{16:[1,46]},{18:[1,47]},i(T,[2,15]),i(T,[2,16]),{21:48,35:29,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se},{21:49,35:29,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se},{21:50,35:29,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se},{21:51,35:29,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se},{21:52,35:29,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se},{21:53,35:29,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se},{5:Ce,22:[1,54],35:56,36:55,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke},i(Ke,[2,31]),i(Ke,[2,33]),i(Ke,[2,34]),i(Ke,[2,37]),i(Ke,[2,38]),i(Ke,[2,39]),i(Ke,[2,40]),i(Ke,[2,41]),i(Ke,[2,42]),i(Ke,[2,43]),i(Ke,[2,44]),i(Ke,[2,45]),i(Ke,[2,46]),i(Ke,[2,47]),i(b,[2,6]),i(T,[2,8]),i(T,[2,12]),i(T,[2,13]),i(T,[2,14]),i(T,[2,20],{36:55,35:56,5:Ce,26:[1,59],40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),i(T,[2,23],{36:55,35:56,5:Ce,26:[1,60],40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),i(T,[2,24],{36:55,35:56,5:Ce,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),i(T,[2,25],{36:55,35:56,5:Ce,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),i(T,[2,26],{36:55,35:56,5:Ce,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),i(T,[2,27],{36:55,35:56,5:Ce,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),{23:[1,61]},i(Ke,[2,32]),i(Ke,[2,48]),i(Ke,[2,49]),i(Ke,[2,50]),i(T,[2,19],{35:29,21:62,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se}),i(T,[2,22],{35:29,21:63,37:ne,38:se,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se}),{24:[1,64]},i(T,[2,18],{36:55,35:56,5:Ce,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),i(T,[2,21],{36:55,35:56,5:Ce,40:de,41:X,42:ge,43:W,44:xe,45:U,46:Fe,47:Pe,48:je,49:Ie,50:Se,51:ke}),i(T,[2,17])],defaultActions:{8:[2,1],9:[2,2]},parseError:function(Et,Gt){if(Gt.recoverable)this.trace(Et);else{var ln=new Error(Et);throw ln.hash=Gt,ln}},parse:function(Et){var Gt=this,ln=[0],xt=[],Pt=[null],Qe=[],Dt=this.table,kt="",On=0,ht=0,zr=2,yt=1,ji=Qe.slice.call(arguments,1),xi=Object.create(this.lexer),Ma={yy:{}};for(var zs in this.yy)Object.prototype.hasOwnProperty.call(this.yy,zs)&&(Ma.yy[zs]=this.yy[zs]);xi.setInput(Et,Ma.yy),Ma.yy.lexer=xi,Ma.yy.parser=this,typeof xi.yylloc>"u"&&(xi.yylloc={});var ao=xi.yylloc;Qe.push(ao);var Tr=xi.options&&xi.options.ranges;typeof Ma.yy.parseError=="function"?this.parseError=Ma.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Fn(){var Pa;return Pa=xt.pop()||xi.lex()||yt,typeof Pa!="number"&&(Pa instanceof Array&&(xt=Pa,Pa=xt.pop()),Pa=Gt.symbols_[Pa]||Pa),Pa}for(var qn,Un,At,wt,on={},fn,An,oo,jo;;){if(Un=ln[ln.length-1],this.defaultActions[Un]?At=this.defaultActions[Un]:((qn===null||typeof qn>"u")&&(qn=Fn()),At=Dt[Un]&&Dt[Un][qn]),typeof At>"u"||!At.length||!At[0]){var $o="";jo=[];for(fn in Dt[Un])this.terminals_[fn]&&fn>zr&&jo.push("'"+this.terminals_[fn]+"'");xi.showPosition?$o="Parse error on line "+(On+1)+`: +`+xi.showPosition()+` +Expecting `+jo.join(", ")+", got '"+(this.terminals_[qn]||qn)+"'":$o="Parse error on line "+(On+1)+": Unexpected "+(qn==yt?"end of input":"'"+(this.terminals_[qn]||qn)+"'"),this.parseError($o,{text:xi.match,token:this.terminals_[qn]||qn,line:xi.yylineno,loc:ao,expected:jo})}if(At[0]instanceof Array&&At.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Un+", token: "+qn);switch(At[0]){case 1:ln.push(qn),Pt.push(xi.yytext),Qe.push(xi.yylloc),ln.push(At[1]),qn=null,ht=xi.yyleng,kt=xi.yytext,On=xi.yylineno,ao=xi.yylloc;break;case 2:if(An=this.productions_[At[1]][1],on.$=Pt[Pt.length-An],on._$={first_line:Qe[Qe.length-(An||1)].first_line,last_line:Qe[Qe.length-1].last_line,first_column:Qe[Qe.length-(An||1)].first_column,last_column:Qe[Qe.length-1].last_column},Tr&&(on._$.range=[Qe[Qe.length-(An||1)].range[0],Qe[Qe.length-1].range[1]]),wt=this.performAction.apply(on,[kt,ht,On,Ma.yy,At[1],Pt,Qe].concat(ji)),typeof wt<"u")return wt;An&&(ln=ln.slice(0,-1*An*2),Pt=Pt.slice(0,-1*An),Qe=Qe.slice(0,-1*An)),ln.push(this.productions_[At[1]][0]),Pt.push(on.$),Qe.push(on._$),oo=Dt[ln[ln.length-2]][ln[ln.length-1]],ln.push(oo);break;case 3:return!0}}return!0}},Ne=function(){var _t={EOF:1,parseError:function(Gt,ln){if(this.yy.parser)this.yy.parser.parseError(Gt,ln);else throw new Error(Gt)},setInput:function(Et,Gt){return this.yy=Gt||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},input:function(){var Et=this._input[0];this.yytext+=Et,this.yyleng++,this.offset++,this.match+=Et,this.matched+=Et;var Gt=Et.match(/(?:\r\n?|\n).*/g);return Gt?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Et},unput:function(Et){var Gt=Et.length,ln=Et.split(/(?:\r\n?|\n)/g);this._input=Et+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Gt),this.offset-=Gt;var xt=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),ln.length-1&&(this.yylineno-=ln.length-1);var Pt=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:ln?(ln.length===xt.length?this.yylloc.first_column:0)+xt[xt.length-ln.length].length-ln[0].length:this.yylloc.first_column-Gt},this.options.ranges&&(this.yylloc.range=[Pt[0],Pt[0]+this.yyleng-Gt]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(Et){this.unput(this.match.slice(Et))},pastInput:function(){var Et=this.matched.substr(0,this.matched.length-this.match.length);return(Et.length>20?"...":"")+Et.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var Et=this.pastInput(),Gt=new Array(Et.length+1).join("-");return Et+this.upcomingInput()+` +`+Gt+"^"},test_match:function(Et,Gt){var ln,xt,Pt;if(this.options.backtrack_lexer&&(Pt={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&&(Pt.yylloc.range=this.yylloc.range.slice(0))),xt=Et[0].match(/(?:\r\n?|\n).*/g),xt&&(this.yylineno+=xt.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:xt?xt[xt.length-1].length-xt[xt.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],ln=this.performAction.call(this,this.yy,this,Gt,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ln)return ln;if(this._backtrack){for(var Qe in Pt)this[Qe]=Pt[Qe];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Et,Gt,ln,xt;this._more||(this.yytext="",this.match="");for(var Pt=this._currentRules(),Qe=0;QeGt[0].length)){if(Gt=ln,xt=Qe,this.options.backtrack_lexer){if(Et=this.test_match(ln,Pt[Qe]),Et!==!1)return Et;if(this._backtrack){Gt=!1;continue}else return!1}else if(!this.options.flex)break}return Gt?(Et=this.test_match(Gt,Pt[xt]),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})},lex:function(){var Gt=this.next();return Gt||this.lex()},begin:function(Gt){this.conditionStack.push(Gt)},popState:function(){var Gt=this.conditionStack.length-1;return Gt>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(Gt){return Gt=this.conditionStack.length-1-Math.abs(Gt||0),Gt>=0?this.conditionStack[Gt]:"INITIAL"},pushState:function(Gt){this.begin(Gt)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(Gt,ln,xt,Pt){switch(xt){case 0:break;case 1:break;case 2:return 32;case 3:break;case 4:return this.begin("title"),13;case 5:return this.popState(),"title_value";case 6:return this.begin("acc_title"),15;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),17;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 25;case 14:return 27;case 15:return 26;case 16:return 28;case 17:return 29;case 18:return 30;case 19:return 31;case 20:this.begin("md_string");break;case 21:return"MD_STR";case 22:this.popState();break;case 23:this.begin("string");break;case 24:this.popState();break;case 25:return"STR";case 26:return this.begin("point_start"),22;case 27:return this.begin("point_x"),23;case 28:this.popState();break;case 29:this.popState(),this.begin("point_y");break;case 30:return this.popState(),24;case 31:return 6;case 32:return 43;case 33:return"COLON";case 34:return 45;case 35:return 44;case 36:return 46;case 37:return 46;case 38:return 47;case 39:return 49;case 40:return 50;case 41:return 48;case 42:return 41;case 43:return 51;case 44:return 42;case 45:return 5;case 46:return 33;case 47:return 40;case 48:return 34}},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,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/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:{point_y:{rules:[30],inclusive:!1},point_x:{rules:[29],inclusive:!1},point_start:{rules:[27,28],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:[21,22],inclusive:!1},string:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,23,26,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],inclusive:!0}}};return _t}();Ft.lexer=Ne;function gn(){this.yy={}}return gn.prototype=Ft,Ft.Parser=gn,new gn}();fve.parser=fve;const Tnn=fve,Pp=f2e();class Cnn{constructor(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){var s,u,d,p,v,b,y,T,_,A,P,R,F,j,K,ee,ie,oe;return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:((s=sh.quadrantChart)==null?void 0:s.chartWidth)||500,chartWidth:((u=sh.quadrantChart)==null?void 0:u.chartHeight)||500,titlePadding:((d=sh.quadrantChart)==null?void 0:d.titlePadding)||10,titleFontSize:((p=sh.quadrantChart)==null?void 0:p.titleFontSize)||20,quadrantPadding:((v=sh.quadrantChart)==null?void 0:v.quadrantPadding)||5,xAxisLabelPadding:((b=sh.quadrantChart)==null?void 0:b.xAxisLabelPadding)||5,yAxisLabelPadding:((y=sh.quadrantChart)==null?void 0:y.yAxisLabelPadding)||5,xAxisLabelFontSize:((T=sh.quadrantChart)==null?void 0:T.xAxisLabelFontSize)||16,yAxisLabelFontSize:((_=sh.quadrantChart)==null?void 0:_.yAxisLabelFontSize)||16,quadrantLabelFontSize:((A=sh.quadrantChart)==null?void 0:A.quadrantLabelFontSize)||16,quadrantTextTopPadding:((P=sh.quadrantChart)==null?void 0:P.quadrantTextTopPadding)||5,pointTextPadding:((R=sh.quadrantChart)==null?void 0:R.pointTextPadding)||5,pointLabelFontSize:((F=sh.quadrantChart)==null?void 0:F.pointLabelFontSize)||12,pointRadius:((j=sh.quadrantChart)==null?void 0:j.pointRadius)||5,xAxisPosition:((K=sh.quadrantChart)==null?void 0:K.xAxisPosition)||"top",yAxisPosition:((ee=sh.quadrantChart)==null?void 0:ee.yAxisPosition)||"left",quadrantInternalBorderStrokeWidth:((ie=sh.quadrantChart)==null?void 0:ie.quadrantInternalBorderStrokeWidth)||1,quadrantExternalBorderStrokeWidth:((oe=sh.quadrantChart)==null?void 0:oe.quadrantExternalBorderStrokeWidth)||2}}getDefaultThemeConfig(){return{quadrant1Fill:Pp.quadrant1Fill,quadrant2Fill:Pp.quadrant2Fill,quadrant3Fill:Pp.quadrant3Fill,quadrant4Fill:Pp.quadrant4Fill,quadrant1TextFill:Pp.quadrant1TextFill,quadrant2TextFill:Pp.quadrant2TextFill,quadrant3TextFill:Pp.quadrant3TextFill,quadrant4TextFill:Pp.quadrant4TextFill,quadrantPointFill:Pp.quadrantPointFill,quadrantPointTextFill:Pp.quadrantPointTextFill,quadrantXAxisTextFill:Pp.quadrantXAxisTextFill,quadrantYAxisTextFill:Pp.quadrantYAxisTextFill,quadrantTitleFill:Pp.quadrantTitleFill,quadrantInternalBorderStrokeFill:Pp.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:Pp.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),Xe.info("clear called")}setData(s){this.data={...this.data,...s}}addPoints(s){this.data.points=[...s,...this.data.points]}setConfig(s){Xe.trace("setConfig called with: ",s),this.config={...this.config,...s}}setThemeConfig(s){Xe.trace("setThemeConfig called with: ",s),this.themeConfig={...this.themeConfig,...s}}calculateSpace(s,u,d,p){const v=this.config.xAxisLabelPadding*2+this.config.xAxisLabelFontSize,b={top:s==="top"&&u?v:0,bottom:s==="bottom"&&u?v:0},y=this.config.yAxisLabelPadding*2+this.config.yAxisLabelFontSize,T={left:this.config.yAxisPosition==="left"&&d?y:0,right:this.config.yAxisPosition==="right"&&d?y:0},_=this.config.titleFontSize+this.config.titlePadding*2,A={top:p?_:0},P=this.config.quadrantPadding+T.left,R=this.config.quadrantPadding+b.top+A.top,F=this.config.chartWidth-this.config.quadrantPadding*2-T.left-T.right,j=this.config.chartHeight-this.config.quadrantPadding*2-b.top-b.bottom-A.top,K=F/2,ee=j/2;return{xAxisSpace:b,yAxisSpace:T,titleSpace:A,quadrantSpace:{quadrantLeft:P,quadrantTop:R,quadrantWidth:F,quadrantHalfWidth:K,quadrantHeight:j,quadrantHalfHeight:ee}}}getAxisLabels(s,u,d,p){const{quadrantSpace:v,titleSpace:b}=p,{quadrantHalfHeight:y,quadrantHeight:T,quadrantLeft:_,quadrantHalfWidth:A,quadrantTop:P,quadrantWidth:R}=v,F=!!this.data.xAxisRightText,j=!!this.data.yAxisTopText,K=[];return this.data.xAxisLeftText&&u&&K.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:_+(F?A/2:0),y:s==="top"?this.config.xAxisLabelPadding+b.top:this.config.xAxisLabelPadding+P+T+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:F?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&u&&K.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:_+A+(F?A/2:0),y:s==="top"?this.config.xAxisLabelPadding+b.top:this.config.xAxisLabelPadding+P+T+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:F?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&d&&K.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+_+R+this.config.quadrantPadding,y:P+T-(j?y/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:j?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&d&&K.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+_+R+this.config.quadrantPadding,y:P+y-(j?y/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:j?"center":"left",horizontalPos:"top",rotation:-90}),K}getQuadrants(s){const{quadrantSpace:u}=s,{quadrantHalfHeight:d,quadrantLeft:p,quadrantHalfWidth:v,quadrantTop:b}=u,y=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:p+v,y:b,width:v,height:d,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:p,y:b,width:v,height:d,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:p,y:b+d,width:v,height:d,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:p+v,y:b+d,width:v,height:d,fill:this.themeConfig.quadrant4Fill}];for(const T of y)T.text.x=T.x+T.width/2,this.data.points.length===0?(T.text.y=T.y+T.height/2,T.text.horizontalPos="middle"):(T.text.y=T.y+this.config.quadrantTextTopPadding,T.text.horizontalPos="top");return y}getQuadrantPoints(s){const{quadrantSpace:u}=s,{quadrantHeight:d,quadrantLeft:p,quadrantTop:v,quadrantWidth:b}=u,y=sD().domain([0,1]).range([p,b+p]),T=sD().domain([0,1]).range([d+v,v]);return this.data.points.map(A=>({x:y(A.x),y:T(A.y),fill:this.themeConfig.quadrantPointFill,radius:this.config.pointRadius,text:{text:A.text,fill:this.themeConfig.quadrantPointTextFill,x:y(A.x),y:T(A.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0}}))}getBorders(s){const u=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:d}=s,{quadrantHalfHeight:p,quadrantHeight:v,quadrantLeft:b,quadrantHalfWidth:y,quadrantTop:T,quadrantWidth:_}=d;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:b-u,y1:T,x2:b+_+u,y2:T},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:b+_,y1:T+u,x2:b+_,y2:T+v-u},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:b-u,y1:T+v,x2:b+_+u,y2:T+v},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:b,y1:T+u,x2:b,y2:T+v-u},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:b+y,y1:T+u,x2:b+y,y2:T+v-u},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:b+u,y1:T+p,x2:b+_-u,y2:T+p}]}getTitle(s){if(s)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(){const s=this.config.showXAxis&&!!(this.data.xAxisLeftText||this.data.xAxisRightText),u=this.config.showYAxis&&!!(this.data.yAxisTopText||this.data.yAxisBottomText),d=this.config.showTitle&&!!this.data.titleText,p=this.data.points.length>0?"bottom":this.config.xAxisPosition,v=this.calculateSpace(p,s,u,d);return{points:this.getQuadrantPoints(v),quadrants:this.getQuadrants(v),axisLabels:this.getAxisLabels(p,s,u,v),borderLines:this.getBorders(v),title:this.getTitle(d)}}}const Snn=qt();function U7(i){return Yf(i.trim(),Snn)}const Rg=new Cnn;function _nn(i){Rg.setData({quadrant1Text:U7(i.text)})}function Ann(i){Rg.setData({quadrant2Text:U7(i.text)})}function Lnn(i){Rg.setData({quadrant3Text:U7(i.text)})}function Mnn(i){Rg.setData({quadrant4Text:U7(i.text)})}function Dnn(i){Rg.setData({xAxisLeftText:U7(i.text)})}function Inn(i){Rg.setData({xAxisRightText:U7(i.text)})}function Onn(i){Rg.setData({yAxisTopText:U7(i.text)})}function Nnn(i){Rg.setData({yAxisBottomText:U7(i.text)})}function Pnn(i,s,u){Rg.addPoints([{x:s,y:u,text:U7(i.text)}])}function Bnn(i){Rg.setConfig({chartWidth:i})}function Fnn(i){Rg.setConfig({chartHeight:i})}function Rnn(){const i=qt(),{themeVariables:s,quadrantChart:u}=i;return u&&Rg.setConfig(u),Rg.setThemeConfig({quadrant1Fill:s.quadrant1Fill,quadrant2Fill:s.quadrant2Fill,quadrant3Fill:s.quadrant3Fill,quadrant4Fill:s.quadrant4Fill,quadrant1TextFill:s.quadrant1TextFill,quadrant2TextFill:s.quadrant2TextFill,quadrant3TextFill:s.quadrant3TextFill,quadrant4TextFill:s.quadrant4TextFill,quadrantPointFill:s.quadrantPointFill,quadrantPointTextFill:s.quadrantPointTextFill,quadrantXAxisTextFill:s.quadrantXAxisTextFill,quadrantYAxisTextFill:s.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:s.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:s.quadrantInternalBorderStrokeFill,quadrantTitleFill:s.quadrantTitleFill}),Rg.setData({titleText:Ap()}),Rg.build()}const jnn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:Tnn,db:{setWidth:Bnn,setHeight:Fnn,setQuadrant1Text:_nn,setQuadrant2Text:Ann,setQuadrant3Text:Lnn,setQuadrant4Text:Mnn,setXAxisLeftText:Dnn,setXAxisRightText:Inn,setYAxisTopText:Onn,setYAxisBottomText:Nnn,addPoint:Pnn,getQuadrantData:Rnn,clear:function(){Rg.clear(),Pg()},setAccTitle:Bg,getAccTitle:Cp,setDiagramTitle:cm,getDiagramTitle:Ap,getAccDescription:_p,setAccDescription:Sp},renderer:{draw:(i,s,u,d)=>{var de,X,ge;function p(W){return W==="top"?"hanging":"middle"}function v(W){return W==="left"?"start":"middle"}function b(W){return`translate(${W.x}, ${W.y}) rotate(${W.rotation||0})`}const y=qt();Xe.debug(`Rendering quadrant chart +`+i);const T=y.securityLevel;let _;T==="sandbox"&&(_=Ir("#i"+s));const P=Ir(T==="sandbox"?_.nodes()[0].contentDocument.body:"body").select(`[id="${s}"]`),R=P.append("g").attr("class","main"),F=((de=y.quadrantChart)==null?void 0:de.chartWidth)||500,j=((X=y.quadrantChart)==null?void 0:X.chartHeight)||500;Ng(P,j,F,((ge=y.quadrantChart)==null?void 0:ge.useMaxWidth)||!0),P.attr("viewBox","0 0 "+F+" "+j),d.db.setHeight(j),d.db.setWidth(F);const K=d.db.getQuadrantData(),ee=R.append("g").attr("class","quadrants"),ie=R.append("g").attr("class","border"),oe=R.append("g").attr("class","data-points"),pe=R.append("g").attr("class","labels"),be=R.append("g").attr("class","title");K.title&&be.append("text").attr("x",0).attr("y",0).attr("fill",K.title.fill).attr("font-size",K.title.fontSize).attr("dominant-baseline",p(K.title.horizontalPos)).attr("text-anchor",v(K.title.verticalPos)).attr("transform",b(K.title)).text(K.title.text),K.borderLines&&ie.selectAll("line").data(K.borderLines).enter().append("line").attr("x1",W=>W.x1).attr("y1",W=>W.y1).attr("x2",W=>W.x2).attr("y2",W=>W.y2).style("stroke",W=>W.strokeFill).style("stroke-width",W=>W.strokeWidth);const ae=ee.selectAll("g.quadrant").data(K.quadrants).enter().append("g").attr("class","quadrant");ae.append("rect").attr("x",W=>W.x).attr("y",W=>W.y).attr("width",W=>W.width).attr("height",W=>W.height).attr("fill",W=>W.fill),ae.append("text").attr("x",0).attr("y",0).attr("fill",W=>W.text.fill).attr("font-size",W=>W.text.fontSize).attr("dominant-baseline",W=>p(W.text.horizontalPos)).attr("text-anchor",W=>v(W.text.verticalPos)).attr("transform",W=>b(W.text)).text(W=>W.text.text),pe.selectAll("g.label").data(K.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text(W=>W.text).attr("fill",W=>W.fill).attr("font-size",W=>W.fontSize).attr("dominant-baseline",W=>p(W.horizontalPos)).attr("text-anchor",W=>v(W.verticalPos)).attr("transform",W=>b(W));const se=oe.selectAll("g.data-point").data(K.points).enter().append("g").attr("class","data-point");se.append("circle").attr("cx",W=>W.x).attr("cy",W=>W.y).attr("r",W=>W.radius).attr("fill",W=>W.fill),se.append("text").attr("x",0).attr("y",0).text(W=>W.text.text).attr("fill",W=>W.text.fill).attr("font-size",W=>W.text.fontSize).attr("dominant-baseline",W=>p(W.text.horizontalPos)).attr("text-anchor",W=>v(W.text.verticalPos)).attr("transform",W=>b(W.text))}},styles:()=>""}},Symbol.toStringTag,{value:"Module"}));var dve=function(){var i=function(Pe,je,Ie,Se){for(Ie=Ie||{},Se=Pe.length;Se--;Ie[Pe[Se]]=je);return Ie},s=[1,10,12,14,16,18,19,21,23],u=[2,6],d=[1,3],p=[1,5],v=[1,6],b=[1,7],y=[1,5,10,12,14,16,18,19,21,23,34,35,36],T=[1,25],_=[1,26],A=[1,28],P=[1,29],R=[1,30],F=[1,31],j=[1,32],K=[1,33],ee=[1,34],ie=[1,35],oe=[1,36],pe=[1,37],be=[1,43],ae=[1,42],ne=[1,47],se=[1,50],de=[1,10,12,14,16,18,19,21,23,34,35,36],X=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],ge=[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],W=[1,64],xe={trace:function(){},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:function(je,Ie,Se,Ce,ke,Ke,Ft){var Ne=Ke.length-1;switch(ke){case 5:Ce.setOrientation(Ke[Ne]);break;case 9:Ce.setDiagramTitle(Ke[Ne].text.trim());break;case 12:Ce.setLineData({text:"",type:"text"},Ke[Ne]);break;case 13:Ce.setLineData(Ke[Ne-1],Ke[Ne]);break;case 14:Ce.setBarData({text:"",type:"text"},Ke[Ne]);break;case 15:Ce.setBarData(Ke[Ne-1],Ke[Ne]);break;case 16:this.$=Ke[Ne].trim(),Ce.setAccTitle(this.$);break;case 17:case 18:this.$=Ke[Ne].trim(),Ce.setAccDescription(this.$);break;case 19:this.$=Ke[Ne-1];break;case 20:this.$=[Number(Ke[Ne-2]),...Ke[Ne]];break;case 21:this.$=[Number(Ke[Ne])];break;case 22:Ce.setXAxisTitle(Ke[Ne]);break;case 23:Ce.setXAxisTitle(Ke[Ne-1]);break;case 24:Ce.setXAxisTitle({type:"text",text:""});break;case 25:Ce.setXAxisBand(Ke[Ne]);break;case 26:Ce.setXAxisRangeData(Number(Ke[Ne-2]),Number(Ke[Ne]));break;case 27:this.$=Ke[Ne-1];break;case 28:this.$=[Ke[Ne-2],...Ke[Ne]];break;case 29:this.$=[Ke[Ne]];break;case 30:Ce.setYAxisTitle(Ke[Ne]);break;case 31:Ce.setYAxisTitle(Ke[Ne-1]);break;case 32:Ce.setYAxisTitle({type:"text",text:""});break;case 33:Ce.setYAxisRangeData(Number(Ke[Ne-2]),Number(Ke[Ne]));break;case 37:this.$={text:Ke[Ne],type:"text"};break;case 38:this.$={text:Ke[Ne],type:"text"};break;case 39:this.$={text:Ke[Ne],type:"markdown"};break;case 40:this.$=Ke[Ne];break;case 41:this.$=Ke[Ne-1]+""+Ke[Ne];break}},table:[i(s,u,{3:1,4:2,7:4,5:d,34:p,35:v,36:b}),{1:[3]},i(s,u,{4:2,7:4,3:8,5:d,34:p,35:v,36:b}),i(s,u,{4:2,7:4,6:9,3:10,5:d,8:[1,11],34:p,35:v,36:b}),{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]},i(y,[2,34]),i(y,[2,35]),i(y,[2,36]),{1:[2,1]},i(s,u,{4:2,7:4,3:21,5:d,34:p,35:v,36:b}),{1:[2,3]},i(y,[2,5]),i(s,[2,7],{4:22,34:p,35:v,36:b}),{11:23,37:24,38:T,39:_,40:27,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe},{11:39,13:38,24:be,27:ae,29:40,30:41,37:24,38:T,39:_,40:27,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe},{11:45,15:44,27:ne,33:46,37:24,38:T,39:_,40:27,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe},{11:49,17:48,24:se,37:24,38:T,39:_,40:27,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe},{11:52,17:51,24:se,37:24,38:T,39:_,40:27,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe},{20:[1,53]},{22:[1,54]},i(de,[2,18]),{1:[2,2]},i(de,[2,8]),i(de,[2,9]),i(X,[2,37],{40:55,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe}),i(X,[2,38]),i(X,[2,39]),i(ge,[2,40]),i(ge,[2,42]),i(ge,[2,43]),i(ge,[2,44]),i(ge,[2,45]),i(ge,[2,46]),i(ge,[2,47]),i(ge,[2,48]),i(ge,[2,49]),i(ge,[2,50]),i(ge,[2,51]),i(de,[2,10]),i(de,[2,22],{30:41,29:56,24:be,27:ae}),i(de,[2,24]),i(de,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:T,39:_,40:27,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe},i(de,[2,11]),i(de,[2,30],{33:60,27:ne}),i(de,[2,32]),{31:[1,61]},i(de,[2,12]),{17:62,24:se},{25:63,27:W},i(de,[2,14]),{17:65,24:se},i(de,[2,16]),i(de,[2,17]),i(ge,[2,41]),i(de,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},i(de,[2,31]),{27:[1,69]},i(de,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},i(de,[2,15]),i(de,[2,26]),i(de,[2,27]),{11:59,32:72,37:24,38:T,39:_,40:27,41:A,42:P,43:R,44:F,45:j,46:K,47:ee,48:ie,49:oe,50:pe},i(de,[2,33]),i(de,[2,19]),{25:73,27:W},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:function(je,Ie){if(Ie.recoverable)this.trace(je);else{var Se=new Error(je);throw Se.hash=Ie,Se}},parse:function(je){var Ie=this,Se=[0],Ce=[],ke=[null],Ke=[],Ft=this.table,Ne="",gn=0,_t=0,Et=2,Gt=1,ln=Ke.slice.call(arguments,1),xt=Object.create(this.lexer),Pt={yy:{}};for(var Qe in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Qe)&&(Pt.yy[Qe]=this.yy[Qe]);xt.setInput(je,Pt.yy),Pt.yy.lexer=xt,Pt.yy.parser=this,typeof xt.yylloc>"u"&&(xt.yylloc={});var Dt=xt.yylloc;Ke.push(Dt);var kt=xt.options&&xt.options.ranges;typeof Pt.yy.parseError=="function"?this.parseError=Pt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function On(){var qn;return qn=Ce.pop()||xt.lex()||Gt,typeof qn!="number"&&(qn instanceof Array&&(Ce=qn,qn=Ce.pop()),qn=Ie.symbols_[qn]||qn),qn}for(var ht,zr,yt,ji,xi={},Ma,zs,ao,Tr;;){if(zr=Se[Se.length-1],this.defaultActions[zr]?yt=this.defaultActions[zr]:((ht===null||typeof ht>"u")&&(ht=On()),yt=Ft[zr]&&Ft[zr][ht]),typeof yt>"u"||!yt.length||!yt[0]){var Fn="";Tr=[];for(Ma in Ft[zr])this.terminals_[Ma]&&Ma>Et&&Tr.push("'"+this.terminals_[Ma]+"'");xt.showPosition?Fn="Parse error on line "+(gn+1)+`: +`+xt.showPosition()+` +Expecting `+Tr.join(", ")+", got '"+(this.terminals_[ht]||ht)+"'":Fn="Parse error on line "+(gn+1)+": Unexpected "+(ht==Gt?"end of input":"'"+(this.terminals_[ht]||ht)+"'"),this.parseError(Fn,{text:xt.match,token:this.terminals_[ht]||ht,line:xt.yylineno,loc:Dt,expected:Tr})}if(yt[0]instanceof Array&&yt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+zr+", token: "+ht);switch(yt[0]){case 1:Se.push(ht),ke.push(xt.yytext),Ke.push(xt.yylloc),Se.push(yt[1]),ht=null,_t=xt.yyleng,Ne=xt.yytext,gn=xt.yylineno,Dt=xt.yylloc;break;case 2:if(zs=this.productions_[yt[1]][1],xi.$=ke[ke.length-zs],xi._$={first_line:Ke[Ke.length-(zs||1)].first_line,last_line:Ke[Ke.length-1].last_line,first_column:Ke[Ke.length-(zs||1)].first_column,last_column:Ke[Ke.length-1].last_column},kt&&(xi._$.range=[Ke[Ke.length-(zs||1)].range[0],Ke[Ke.length-1].range[1]]),ji=this.performAction.apply(xi,[Ne,_t,gn,Pt.yy,yt[1],ke,Ke].concat(ln)),typeof ji<"u")return ji;zs&&(Se=Se.slice(0,-1*zs*2),ke=ke.slice(0,-1*zs),Ke=Ke.slice(0,-1*zs)),Se.push(this.productions_[yt[1]][0]),ke.push(xi.$),Ke.push(xi._$),ao=Ft[Se[Se.length-2]][Se[Se.length-1]],Se.push(ao);break;case 3:return!0}}return!0}},U=function(){var Pe={EOF:1,parseError:function(Ie,Se){if(this.yy.parser)this.yy.parser.parseError(Ie,Se);else throw new Error(Ie)},setInput:function(je,Ie){return this.yy=Ie||this.yy||{},this._input=je,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},input:function(){var je=this._input[0];this.yytext+=je,this.yyleng++,this.offset++,this.match+=je,this.matched+=je;var Ie=je.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),je},unput:function(je){var Ie=je.length,Se=je.split(/(?:\r\n?|\n)/g);this._input=je+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Ie),this.offset-=Ie;var Ce=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),Se.length-1&&(this.yylineno-=Se.length-1);var ke=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:Se?(Se.length===Ce.length?this.yylloc.first_column:0)+Ce[Ce.length-Se.length].length-Se[0].length:this.yylloc.first_column-Ie},this.options.ranges&&(this.yylloc.range=[ke[0],ke[0]+this.yyleng-Ie]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(je){this.unput(this.match.slice(je))},pastInput:function(){var je=this.matched.substr(0,this.matched.length-this.match.length);return(je.length>20?"...":"")+je.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var je=this.match;return je.length<20&&(je+=this._input.substr(0,20-je.length)),(je.substr(0,20)+(je.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var je=this.pastInput(),Ie=new Array(je.length+1).join("-");return je+this.upcomingInput()+` +`+Ie+"^"},test_match:function(je,Ie){var Se,Ce,ke;if(this.options.backtrack_lexer&&(ke={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&&(ke.yylloc.range=this.yylloc.range.slice(0))),Ce=je[0].match(/(?:\r\n?|\n).*/g),Ce&&(this.yylineno+=Ce.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Ce?Ce[Ce.length-1].length-Ce[Ce.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+je[0].length},this.yytext+=je[0],this.match+=je[0],this.matches=je,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(je[0].length),this.matched+=je[0],Se=this.performAction.call(this,this.yy,this,Ie,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Se)return Se;if(this._backtrack){for(var Ke in ke)this[Ke]=ke[Ke];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var je,Ie,Se,Ce;this._more||(this.yytext="",this.match="");for(var ke=this._currentRules(),Ke=0;KeIe[0].length)){if(Ie=Se,Ce=Ke,this.options.backtrack_lexer){if(je=this.test_match(Se,ke[Ke]),je!==!1)return je;if(this._backtrack){Ie=!1;continue}else return!1}else if(!this.options.flex)break}return Ie?(je=this.test_match(Ie,ke[Ce]),je!==!1?je:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var Ie=this.next();return Ie||this.lex()},begin:function(Ie){this.conditionStack.push(Ie)},popState:function(){var Ie=this.conditionStack.length-1;return Ie>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(Ie){return Ie=this.conditionStack.length-1-Math.abs(Ie||0),Ie>=0?this.conditionStack[Ie]:"INITIAL"},pushState:function(Ie){this.begin(Ie)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(Ie,Se,Ce,ke){switch(Ce){case 0:break;case 1:break;case 2:return this.popState(),34;case 3:return this.popState(),34;case 4:return 34;case 5:break;case 6:return 10;case 7:return this.pushState("acc_title"),19;case 8:return this.popState(),"acc_title_value";case 9:return this.pushState("acc_descr"),21;case 10:return this.popState(),"acc_descr_value";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";case 17:return this.pushState("axis_data"),"Y_AXIS";case 18:return this.pushState("axis_band_data"),24;case 19:return 31;case 20:return this.pushState("data"),16;case 21:return this.pushState("data"),18;case 22:return this.pushState("data_inner"),24;case 23:return 27;case 24:return this.popState(),26;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}},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\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n\(\?:`))/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 Pe}();xe.lexer=U;function Fe(){this.yy={}}return Fe.prototype=xe,xe.Parser=Fe,new Fe}();dve.parser=dve;const $nn=dve;function fGe(i){return i.type==="bar"}function dGe(i){return i.type==="band"}function $R(i){return i.type==="linear"}class gGe{constructor(s){this.parentGroup=s}getMaxDimension(s,u){if(!this.parentGroup)return{width:s.reduce((v,b)=>Math.max(b.length,v),0)*u,height:u};const d={width:0,height:0},p=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",u);for(const v of s){const b=RZt(p,1,v),y=b?b.width:v.length*u,T=b?b.height:u;d.width=Math.max(d.width,y),d.height=Math.max(d.height,T)}return p.remove(),d}}const pGe=.7,bGe=.2;class mGe{constructor(s,u,d,p){this.axisConfig=s,this.title=u,this.textDimensionCalculator=d,this.axisThemeConfig=p,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"}setRange(s){this.range=s,this.axisPosition==="left"||this.axisPosition==="right"?this.boundingRect.height=s[1]-s[0]:this.boundingRect.width=s[1]-s[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(s){this.axisPosition=s,this.setRange(this.range)}getTickDistance(){const s=this.getRange();return Math.abs(s[0]-s[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map(s=>s.toString()),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){pGe*this.getTickDistance()>this.outerPadding*2&&(this.outerPadding=Math.floor(pGe*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(s){let u=s.height;if(this.axisConfig.showAxisLine&&u>this.axisConfig.axisLineWidth&&(u-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const d=this.getLabelDimension(),p=bGe*s.width;this.outerPadding=Math.min(d.width/2,p);const v=d.height+this.axisConfig.labelPadding*2;this.labelTextHeight=d.height,v<=u&&(u-=v,this.showLabel=!0)}if(this.axisConfig.showTick&&u>=this.axisConfig.tickLength&&(this.showTick=!0,u-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const d=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),p=d.height+this.axisConfig.titlePadding*2;this.titleTextHeight=d.height,p<=u&&(u-=p,this.showTitle=!0)}this.boundingRect.width=s.width,this.boundingRect.height=s.height-u}calculateSpaceIfDrawnVertical(s){let u=s.width;if(this.axisConfig.showAxisLine&&u>this.axisConfig.axisLineWidth&&(u-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const d=this.getLabelDimension(),p=bGe*s.height;this.outerPadding=Math.min(d.height/2,p);const v=d.width+this.axisConfig.labelPadding*2;v<=u&&(u-=v,this.showLabel=!0)}if(this.axisConfig.showTick&&u>=this.axisConfig.tickLength&&(this.showTick=!0,u-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const d=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),p=d.height+this.axisConfig.titlePadding*2;this.titleTextHeight=d.height,p<=u&&(u-=p,this.showTitle=!0)}this.boundingRect.width=s.width-u,this.boundingRect.height=s.height}calculateSpace(s){return this.axisPosition==="left"||this.axisPosition==="right"?this.calculateSpaceIfDrawnVertical(s):this.calculateSpaceIfDrawnHorizontally(s),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(s){this.boundingRect.x=s.x,this.boundingRect.y=s.y}getDrawableElementsForLeftAxis(){const s=[];if(this.showAxisLine){const u=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;s.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${u},${this.boundingRect.y} L ${u},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&s.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map(u=>({text:u.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(u),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"}))}),this.showTick){const u=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);s.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map(d=>({path:`M ${u},${this.getScaleValue(d)} L ${u-this.axisConfig.tickLength},${this.getScaleValue(d)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&s.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"}]}),s}getDrawableElementsForBottomAxis(){const s=[];if(this.showAxisLine){const u=this.boundingRect.y+this.axisConfig.axisLineWidth/2;s.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${u} L ${this.boundingRect.x+this.boundingRect.width},${u}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&s.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map(u=>({text:u.toString(),x:this.getScaleValue(u),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){const u=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);s.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map(d=>({path:`M ${this.getScaleValue(d)},${u} L ${this.getScaleValue(d)},${u+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&s.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"}]}),s}getDrawableElementsForTopAxis(){const s=[];if(this.showAxisLine){const u=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;s.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${u} L ${this.boundingRect.x+this.boundingRect.width},${u}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&s.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map(u=>({text:u.toString(),x:this.getScaleValue(u),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){const u=this.boundingRect.y;s.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map(d=>({path:`M ${this.getScaleValue(d)},${u+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(d)},${u+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&s.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"}]}),s}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():[]}}class znn extends mGe{constructor(s,u,d,p,v){super(s,p,v,u),this.categories=d,this.scale=qpe().domain(this.categories).range(this.getRange())}setRange(s){super.setRange(s)}recalculateScale(){this.scale=qpe().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),Xe.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(s){return this.scale(s)||this.getRange()[0]}}class qnn extends mGe{constructor(s,u,d,p,v){super(s,p,v,u),this.domain=d,this.scale=sD().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){const s=[...this.domain];this.axisPosition==="left"&&s.reverse(),this.scale=sD().domain(s).range(this.getRange())}getScaleValue(s){return this.scale(s)}}function vGe(i,s,u,d){const p=new gGe(d);return dGe(i)?new znn(s,u,i.categories,i.title,p):new qnn(s,u,[i.min,i.max],i.title,p)}class Hnn{constructor(s,u,d,p){this.textDimensionCalculator=s,this.chartConfig=u,this.chartData=d,this.chartThemeConfig=p,this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}setBoundingBoxXY(s){this.boundingRect.x=s.x,this.boundingRect.y=s.y}calculateSpace(s){const u=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),d=Math.max(u.width,s.width),p=u.height+2*this.chartConfig.titlePadding;return u.width<=d&&u.height<=p&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=d,this.boundingRect.height=p,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){const s=[];return this.showChartTitle&&s.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}]}),s}}function Vnn(i,s,u,d){const p=new gGe(d);return new Hnn(p,i,s,u)}class Unn{constructor(s,u,d,p,v){this.plotData=s,this.xAxis=u,this.yAxis=d,this.orientation=p,this.plotIndex=v}getDrawableElement(){const s=this.plotData.data.map(d=>[this.xAxis.getScaleValue(d[0]),this.yAxis.getScaleValue(d[1])]);let u;return this.orientation==="horizontal"?u=k7().y(d=>d[0]).x(d=>d[1])(s):u=k7().x(d=>d[0]).y(d=>d[1])(s),u?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:u,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}}class Gnn{constructor(s,u,d,p,v,b){this.barData=s,this.boundingRect=u,this.xAxis=d,this.yAxis=p,this.orientation=v,this.plotIndex=b}getDrawableElement(){const s=this.barData.data.map(v=>[this.xAxis.getScaleValue(v[0]),this.yAxis.getScaleValue(v[1])]),u=.05,d=Math.min(this.xAxis.getAxisOuterPadding()*2,this.xAxis.getTickDistance())*(1-u),p=d/2;return this.orientation==="horizontal"?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:s.map(v=>({x:this.boundingRect.x,y:v[0]-p,height:d,width:v[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:s.map(v=>({x:v[0]-p,y:v[1],width:d,height:this.boundingRect.y+this.boundingRect.height-v[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]}}class Knn{constructor(s,u,d){this.chartConfig=s,this.chartData=u,this.chartThemeConfig=d,this.boundingRect={x:0,y:0,width:0,height:0}}setAxes(s,u){this.xAxis=s,this.yAxis=u}setBoundingBoxXY(s){this.boundingRect.x=s.x,this.boundingRect.y=s.y}calculateSpace(s){return this.boundingRect.width=s.width,this.boundingRect.height=s.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!(this.xAxis&&this.yAxis))throw Error("Axes must be passed to render Plots");const s=[];for(const[u,d]of this.chartData.plots.entries())switch(d.type){case"line":{const p=new Unn(d,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,u);s.push(...p.getDrawableElement())}break;case"bar":{const p=new Gnn(d,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,u);s.push(...p.getDrawableElement())}break}return s}}function Wnn(i,s,u){return new Knn(i,s,u)}class Ynn{constructor(s,u,d,p){this.chartConfig=s,this.chartData=u,this.componentStore={title:Vnn(s,u,d,p),plot:Wnn(s,u,d),xAxis:vGe(u.xAxis,s.xAxis,{titleColor:d.xAxisTitleColor,labelColor:d.xAxisLabelColor,tickColor:d.xAxisTickColor,axisLineColor:d.xAxisLineColor},p),yAxis:vGe(u.yAxis,s.yAxis,{titleColor:d.yAxisTitleColor,labelColor:d.yAxisLabelColor,tickColor:d.yAxisTickColor,axisLineColor:d.yAxisLineColor},p)}}calculateVerticalSpace(){let s=this.chartConfig.width,u=this.chartConfig.height,d=0,p=0,v=Math.floor(s*this.chartConfig.plotReservedSpacePercent/100),b=Math.floor(u*this.chartConfig.plotReservedSpacePercent/100),y=this.componentStore.plot.calculateSpace({width:v,height:b});s-=y.width,u-=y.height,y=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:u}),p=y.height,u-=y.height,this.componentStore.xAxis.setAxisPosition("bottom"),y=this.componentStore.xAxis.calculateSpace({width:s,height:u}),u-=y.height,this.componentStore.yAxis.setAxisPosition("left"),y=this.componentStore.yAxis.calculateSpace({width:s,height:u}),d=y.width,s-=y.width,s>0&&(v+=s,s=0),u>0&&(b+=u,u=0),this.componentStore.plot.calculateSpace({width:v,height:b}),this.componentStore.plot.setBoundingBoxXY({x:d,y:p}),this.componentStore.xAxis.setRange([d,d+v]),this.componentStore.xAxis.setBoundingBoxXY({x:d,y:p+b}),this.componentStore.yAxis.setRange([p,p+b]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:p}),this.chartData.plots.some(T=>fGe(T))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let s=this.chartConfig.width,u=this.chartConfig.height,d=0,p=0,v=0,b=Math.floor(s*this.chartConfig.plotReservedSpacePercent/100),y=Math.floor(u*this.chartConfig.plotReservedSpacePercent/100),T=this.componentStore.plot.calculateSpace({width:b,height:y});s-=T.width,u-=T.height,T=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:u}),d=T.height,u-=T.height,this.componentStore.xAxis.setAxisPosition("left"),T=this.componentStore.xAxis.calculateSpace({width:s,height:u}),s-=T.width,p=T.width,this.componentStore.yAxis.setAxisPosition("top"),T=this.componentStore.yAxis.calculateSpace({width:s,height:u}),u-=T.height,v=d+T.height,s>0&&(b+=s,s=0),u>0&&(y+=u,u=0),this.componentStore.plot.calculateSpace({width:b,height:y}),this.componentStore.plot.setBoundingBoxXY({x:p,y:v}),this.componentStore.yAxis.setRange([p,p+b]),this.componentStore.yAxis.setBoundingBoxXY({x:p,y:d}),this.componentStore.xAxis.setRange([v,v+y]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:v}),this.chartData.plots.some(_=>fGe(_))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){this.chartConfig.chartOrientation==="horizontal"?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();const s=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(const u of Object.values(this.componentStore))s.push(...u.getDrawableElements());return s}}class Xnn{static build(s,u,d,p){return new Ynn(s,u,d,p).getDrawableElement()}}let zR=0,wGe,qR=xGe(),HR=yGe(),el=kGe(),gve=HR.plotColorPalette.split(",").map(i=>i.trim()),gJ=!1,pve=!1;function yGe(){const i=f2e(),s=Vh();return JF(i.xyChart,s.themeVariables.xyChart)}function xGe(){const i=Vh();return JF(sh.xyChart,i.xyChart)}function kGe(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function bve(i){const s=Vh();return Yf(i.trim(),s)}function Qnn(i){wGe=i}function Jnn(i){i==="horizontal"?qR.chartOrientation="horizontal":qR.chartOrientation="vertical"}function Znn(i){el.xAxis.title=bve(i.text)}function EGe(i,s){el.xAxis={type:"linear",title:el.xAxis.title,min:i,max:s},gJ=!0}function ern(i){el.xAxis={type:"band",title:el.xAxis.title,categories:i.map(s=>bve(s.text))},gJ=!0}function trn(i){el.yAxis.title=bve(i.text)}function nrn(i,s){el.yAxis={type:"linear",title:el.yAxis.title,min:i,max:s},pve=!0}function rrn(i){const s=Math.min(...i),u=Math.max(...i),d=$R(el.yAxis)?el.yAxis.min:1/0,p=$R(el.yAxis)?el.yAxis.max:-1/0;el.yAxis={type:"linear",title:el.yAxis.title,min:Math.min(d,s),max:Math.max(p,u)}}function TGe(i){let s=[];if(i.length===0)return s;if(!gJ){const u=$R(el.xAxis)?el.xAxis.min:1/0,d=$R(el.xAxis)?el.xAxis.max:-1/0;EGe(Math.min(u,1),Math.max(d,i.length))}if(pve||rrn(i),dGe(el.xAxis)&&(s=el.xAxis.categories.map((u,d)=>[u,i[d]])),$R(el.xAxis)){const u=el.xAxis.min,d=el.xAxis.max,p=(d-u+1)/i.length,v=[];for(let b=u;b<=d;b+=p)v.push(`${b}`);s=v.map((b,y)=>[b,i[y]])}return s}function CGe(i){return gve[i===0?0:i%gve.length]}function irn(i,s){const u=TGe(s);el.plots.push({type:"line",strokeFill:CGe(zR),strokeWidth:2,data:u}),zR++}function srn(i,s){const u=TGe(s);el.plots.push({type:"bar",fill:CGe(zR),data:u}),zR++}function arn(){if(el.plots.length===0)throw Error("No Plot to render, please provide a plot with some data");return el.title=Ap(),Xnn.build(qR,el,HR,wGe)}function orn(){return HR}function crn(){return qR}const urn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:$nn,db:{getDrawableElem:arn,clear:function(){Pg(),zR=0,qR=xGe(),el=kGe(),HR=yGe(),gve=HR.plotColorPalette.split(",").map(i=>i.trim()),gJ=!1,pve=!1},setAccTitle:Bg,getAccTitle:Cp,setDiagramTitle:cm,getDiagramTitle:Ap,getAccDescription:_p,setAccDescription:Sp,setOrientation:Jnn,setXAxisTitle:Znn,setXAxisRangeData:EGe,setXAxisBand:ern,setYAxisTitle:trn,setYAxisRangeData:nrn,setLineData:irn,setBarData:srn,setTmpSVGG:Qnn,getChartThemeConfig:orn,getChartConfig:crn},renderer:{draw:(i,s,u,d)=>{const p=d.db,v=p.getChartThemeConfig(),b=p.getChartConfig();function y(ee){return ee==="top"?"text-before-edge":"middle"}function T(ee){return ee==="left"?"start":ee==="right"?"end":"middle"}function _(ee){return`translate(${ee.x}, ${ee.y}) rotate(${ee.rotation||0})`}Xe.debug(`Rendering xychart chart +`+i);const A=rR(s),P=A.append("g").attr("class","main"),R=P.append("rect").attr("width",b.width).attr("height",b.height).attr("class","background");Ng(A,b.height,b.width,!0),A.attr("viewBox",`0 0 ${b.width} ${b.height}`),R.attr("fill",v.backgroundColor),p.setTmpSVGG(A.append("g").attr("class","mermaid-tmp-group"));const F=p.getDrawableElem(),j={};function K(ee){let ie=P,oe="";for(const[pe]of ee.entries()){let be=P;pe>0&&j[oe]&&(be=j[oe]),oe+=ee[pe],ie=j[oe],ie||(ie=j[oe]=be.append("g").attr("class",ee[pe]))}return ie}for(const ee of F){if(ee.data.length===0)continue;const ie=K(ee.groupTexts);switch(ee.type){case"rect":ie.selectAll("rect").data(ee.data).enter().append("rect").attr("x",oe=>oe.x).attr("y",oe=>oe.y).attr("width",oe=>oe.width).attr("height",oe=>oe.height).attr("fill",oe=>oe.fill).attr("stroke",oe=>oe.strokeFill).attr("stroke-width",oe=>oe.strokeWidth);break;case"text":ie.selectAll("text").data(ee.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",oe=>oe.fill).attr("font-size",oe=>oe.fontSize).attr("dominant-baseline",oe=>y(oe.verticalPos)).attr("text-anchor",oe=>T(oe.horizontalPos)).attr("transform",oe=>_(oe)).text(oe=>oe.text);break;case"path":ie.selectAll("path").data(ee.data).enter().append("path").attr("d",oe=>oe.path).attr("fill",oe=>oe.fill?oe.fill:"none").attr("stroke",oe=>oe.strokeFill).attr("stroke-width",oe=>oe.strokeWidth);break}}}}}},Symbol.toStringTag,{value:"Module"}));var mve=function(){var i=function(_t,Et,Gt,ln){for(Gt=Gt||{},ln=_t.length;ln--;Gt[_t[ln]]=Et);return Gt},s=[1,3],u=[1,4],d=[1,5],p=[1,6],v=[5,6,8,9,11,13,31,32,33,34,35,36,44,62,63],b=[1,18],y=[2,7],T=[1,22],_=[1,23],A=[1,24],P=[1,25],R=[1,26],F=[1,27],j=[1,20],K=[1,28],ee=[1,29],ie=[62,63],oe=[5,8,9,11,13,31,32,33,34,35,36,44,51,53,62,63],pe=[1,47],be=[1,48],ae=[1,49],ne=[1,50],se=[1,51],de=[1,52],X=[1,53],ge=[53,54],W=[1,64],xe=[1,60],U=[1,61],Fe=[1,62],Pe=[1,63],je=[1,65],Ie=[1,69],Se=[1,70],Ce=[1,67],ke=[1,68],Ke=[5,8,9,11,13,31,32,33,34,35,36,44,62,63],Ft={trace:function(){},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,requirementType:17,requirementName:18,STRUCT_START:19,requirementBody:20,ID:21,COLONSEP:22,id:23,TEXT:24,text:25,RISK:26,riskLevel:27,VERIFYMTHD:28,verifyType:29,STRUCT_STOP:30,REQUIREMENT:31,FUNCTIONAL_REQUIREMENT:32,INTERFACE_REQUIREMENT:33,PERFORMANCE_REQUIREMENT:34,PHYSICAL_REQUIREMENT:35,DESIGN_CONSTRAINT:36,LOW_RISK:37,MED_RISK:38,HIGH_RISK:39,VERIFY_ANALYSIS:40,VERIFY_DEMONSTRATION:41,VERIFY_INSPECTION:42,VERIFY_TEST:43,ELEMENT:44,elementName:45,elementBody:46,TYPE:47,type:48,DOCREF:49,ref:50,END_ARROW_L:51,relationship:52,LINE:53,END_ARROW_R:54,CONTAINS:55,COPIES:56,DERIVES:57,SATISFIES:58,VERIFIES:59,REFINES:60,TRACES:61,unqString:62,qString:63,$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",19:"STRUCT_START",21:"ID",22:"COLONSEP",24:"TEXT",26:"RISK",28:"VERIFYMTHD",30:"STRUCT_STOP",31:"REQUIREMENT",32:"FUNCTIONAL_REQUIREMENT",33:"INTERFACE_REQUIREMENT",34:"PERFORMANCE_REQUIREMENT",35:"PHYSICAL_REQUIREMENT",36:"DESIGN_CONSTRAINT",37:"LOW_RISK",38:"MED_RISK",39:"HIGH_RISK",40:"VERIFY_ANALYSIS",41:"VERIFY_DEMONSTRATION",42:"VERIFY_INSPECTION",43:"VERIFY_TEST",44:"ELEMENT",47:"TYPE",49:"DOCREF",51:"END_ARROW_L",53:"LINE",54:"END_ARROW_R",55:"CONTAINS",56:"COPIES",57:"DERIVES",58:"SATISFIES",59:"VERIFIES",60:"REFINES",61:"TRACES",62:"unqString",63:"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],[14,5],[20,5],[20,5],[20,5],[20,5],[20,2],[20,1],[17,1],[17,1],[17,1],[17,1],[17,1],[17,1],[27,1],[27,1],[27,1],[29,1],[29,1],[29,1],[29,1],[15,5],[46,5],[46,5],[46,2],[46,1],[16,5],[16,5],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[18,1],[18,1],[23,1],[23,1],[25,1],[25,1],[45,1],[45,1],[48,1],[48,1],[50,1],[50,1]],performAction:function(Et,Gt,ln,xt,Pt,Qe,Dt){var kt=Qe.length-1;switch(Pt){case 4:this.$=Qe[kt].trim(),xt.setAccTitle(this.$);break;case 5:case 6:this.$=Qe[kt].trim(),xt.setAccDescription(this.$);break;case 7:this.$=[];break;case 13:xt.addRequirement(Qe[kt-3],Qe[kt-4]);break;case 14:xt.setNewReqId(Qe[kt-2]);break;case 15:xt.setNewReqText(Qe[kt-2]);break;case 16:xt.setNewReqRisk(Qe[kt-2]);break;case 17:xt.setNewReqVerifyMethod(Qe[kt-2]);break;case 20:this.$=xt.RequirementType.REQUIREMENT;break;case 21:this.$=xt.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 22:this.$=xt.RequirementType.INTERFACE_REQUIREMENT;break;case 23:this.$=xt.RequirementType.PERFORMANCE_REQUIREMENT;break;case 24:this.$=xt.RequirementType.PHYSICAL_REQUIREMENT;break;case 25:this.$=xt.RequirementType.DESIGN_CONSTRAINT;break;case 26:this.$=xt.RiskLevel.LOW_RISK;break;case 27:this.$=xt.RiskLevel.MED_RISK;break;case 28:this.$=xt.RiskLevel.HIGH_RISK;break;case 29:this.$=xt.VerifyType.VERIFY_ANALYSIS;break;case 30:this.$=xt.VerifyType.VERIFY_DEMONSTRATION;break;case 31:this.$=xt.VerifyType.VERIFY_INSPECTION;break;case 32:this.$=xt.VerifyType.VERIFY_TEST;break;case 33:xt.addElement(Qe[kt-3]);break;case 34:xt.setNewElementType(Qe[kt-2]);break;case 35:xt.setNewElementDocRef(Qe[kt-2]);break;case 38:xt.addRelationship(Qe[kt-2],Qe[kt],Qe[kt-4]);break;case 39:xt.addRelationship(Qe[kt-2],Qe[kt-4],Qe[kt]);break;case 40:this.$=xt.Relationships.CONTAINS;break;case 41:this.$=xt.Relationships.COPIES;break;case 42:this.$=xt.Relationships.DERIVES;break;case 43:this.$=xt.Relationships.SATISFIES;break;case 44:this.$=xt.Relationships.VERIFIES;break;case 45:this.$=xt.Relationships.REFINES;break;case 46:this.$=xt.Relationships.TRACES;break}},table:[{3:1,4:2,6:s,9:u,11:d,13:p},{1:[3]},{3:8,4:2,5:[1,7],6:s,9:u,11:d,13:p},{5:[1,9]},{10:[1,10]},{12:[1,11]},i(v,[2,6]),{3:12,4:2,6:s,9:u,11:d,13:p},{1:[2,2]},{4:17,5:b,7:13,8:y,9:u,11:d,13:p,14:14,15:15,16:16,17:19,23:21,31:T,32:_,33:A,34:P,35:R,36:F,44:j,62:K,63:ee},i(v,[2,4]),i(v,[2,5]),{1:[2,1]},{8:[1,30]},{4:17,5:b,7:31,8:y,9:u,11:d,13:p,14:14,15:15,16:16,17:19,23:21,31:T,32:_,33:A,34:P,35:R,36:F,44:j,62:K,63:ee},{4:17,5:b,7:32,8:y,9:u,11:d,13:p,14:14,15:15,16:16,17:19,23:21,31:T,32:_,33:A,34:P,35:R,36:F,44:j,62:K,63:ee},{4:17,5:b,7:33,8:y,9:u,11:d,13:p,14:14,15:15,16:16,17:19,23:21,31:T,32:_,33:A,34:P,35:R,36:F,44:j,62:K,63:ee},{4:17,5:b,7:34,8:y,9:u,11:d,13:p,14:14,15:15,16:16,17:19,23:21,31:T,32:_,33:A,34:P,35:R,36:F,44:j,62:K,63:ee},{4:17,5:b,7:35,8:y,9:u,11:d,13:p,14:14,15:15,16:16,17:19,23:21,31:T,32:_,33:A,34:P,35:R,36:F,44:j,62:K,63:ee},{18:36,62:[1,37],63:[1,38]},{45:39,62:[1,40],63:[1,41]},{51:[1,42],53:[1,43]},i(ie,[2,20]),i(ie,[2,21]),i(ie,[2,22]),i(ie,[2,23]),i(ie,[2,24]),i(ie,[2,25]),i(oe,[2,49]),i(oe,[2,50]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{19:[1,44]},{19:[2,47]},{19:[2,48]},{19:[1,45]},{19:[2,53]},{19:[2,54]},{52:46,55:pe,56:be,57:ae,58:ne,59:se,60:de,61:X},{52:54,55:pe,56:be,57:ae,58:ne,59:se,60:de,61:X},{5:[1,55]},{5:[1,56]},{53:[1,57]},i(ge,[2,40]),i(ge,[2,41]),i(ge,[2,42]),i(ge,[2,43]),i(ge,[2,44]),i(ge,[2,45]),i(ge,[2,46]),{54:[1,58]},{5:W,20:59,21:xe,24:U,26:Fe,28:Pe,30:je},{5:Ie,30:Se,46:66,47:Ce,49:ke},{23:71,62:K,63:ee},{23:72,62:K,63:ee},i(Ke,[2,13]),{22:[1,73]},{22:[1,74]},{22:[1,75]},{22:[1,76]},{5:W,20:77,21:xe,24:U,26:Fe,28:Pe,30:je},i(Ke,[2,19]),i(Ke,[2,33]),{22:[1,78]},{22:[1,79]},{5:Ie,30:Se,46:80,47:Ce,49:ke},i(Ke,[2,37]),i(Ke,[2,38]),i(Ke,[2,39]),{23:81,62:K,63:ee},{25:82,62:[1,83],63:[1,84]},{27:85,37:[1,86],38:[1,87],39:[1,88]},{29:89,40:[1,90],41:[1,91],42:[1,92],43:[1,93]},i(Ke,[2,18]),{48:94,62:[1,95],63:[1,96]},{50:97,62:[1,98],63:[1,99]},i(Ke,[2,36]),{5:[1,100]},{5:[1,101]},{5:[2,51]},{5:[2,52]},{5:[1,102]},{5:[2,26]},{5:[2,27]},{5:[2,28]},{5:[1,103]},{5:[2,29]},{5:[2,30]},{5:[2,31]},{5:[2,32]},{5:[1,104]},{5:[2,55]},{5:[2,56]},{5:[1,105]},{5:[2,57]},{5:[2,58]},{5:W,20:106,21:xe,24:U,26:Fe,28:Pe,30:je},{5:W,20:107,21:xe,24:U,26:Fe,28:Pe,30:je},{5:W,20:108,21:xe,24:U,26:Fe,28:Pe,30:je},{5:W,20:109,21:xe,24:U,26:Fe,28:Pe,30:je},{5:Ie,30:Se,46:110,47:Ce,49:ke},{5:Ie,30:Se,46:111,47:Ce,49:ke},i(Ke,[2,14]),i(Ke,[2,15]),i(Ke,[2,16]),i(Ke,[2,17]),i(Ke,[2,34]),i(Ke,[2,35])],defaultActions:{8:[2,2],12:[2,1],30:[2,3],31:[2,8],32:[2,9],33:[2,10],34:[2,11],35:[2,12],37:[2,47],38:[2,48],40:[2,53],41:[2,54],83:[2,51],84:[2,52],86:[2,26],87:[2,27],88:[2,28],90:[2,29],91:[2,30],92:[2,31],93:[2,32],95:[2,55],96:[2,56],98:[2,57],99:[2,58]},parseError:function(Et,Gt){if(Gt.recoverable)this.trace(Et);else{var ln=new Error(Et);throw ln.hash=Gt,ln}},parse:function(Et){var Gt=this,ln=[0],xt=[],Pt=[null],Qe=[],Dt=this.table,kt="",On=0,ht=0,zr=2,yt=1,ji=Qe.slice.call(arguments,1),xi=Object.create(this.lexer),Ma={yy:{}};for(var zs in this.yy)Object.prototype.hasOwnProperty.call(this.yy,zs)&&(Ma.yy[zs]=this.yy[zs]);xi.setInput(Et,Ma.yy),Ma.yy.lexer=xi,Ma.yy.parser=this,typeof xi.yylloc>"u"&&(xi.yylloc={});var ao=xi.yylloc;Qe.push(ao);var Tr=xi.options&&xi.options.ranges;typeof Ma.yy.parseError=="function"?this.parseError=Ma.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Fn(){var Pa;return Pa=xt.pop()||xi.lex()||yt,typeof Pa!="number"&&(Pa instanceof Array&&(xt=Pa,Pa=xt.pop()),Pa=Gt.symbols_[Pa]||Pa),Pa}for(var qn,Un,At,wt,on={},fn,An,oo,jo;;){if(Un=ln[ln.length-1],this.defaultActions[Un]?At=this.defaultActions[Un]:((qn===null||typeof qn>"u")&&(qn=Fn()),At=Dt[Un]&&Dt[Un][qn]),typeof At>"u"||!At.length||!At[0]){var $o="";jo=[];for(fn in Dt[Un])this.terminals_[fn]&&fn>zr&&jo.push("'"+this.terminals_[fn]+"'");xi.showPosition?$o="Parse error on line "+(On+1)+`: +`+xi.showPosition()+` +Expecting `+jo.join(", ")+", got '"+(this.terminals_[qn]||qn)+"'":$o="Parse error on line "+(On+1)+": Unexpected "+(qn==yt?"end of input":"'"+(this.terminals_[qn]||qn)+"'"),this.parseError($o,{text:xi.match,token:this.terminals_[qn]||qn,line:xi.yylineno,loc:ao,expected:jo})}if(At[0]instanceof Array&&At.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Un+", token: "+qn);switch(At[0]){case 1:ln.push(qn),Pt.push(xi.yytext),Qe.push(xi.yylloc),ln.push(At[1]),qn=null,ht=xi.yyleng,kt=xi.yytext,On=xi.yylineno,ao=xi.yylloc;break;case 2:if(An=this.productions_[At[1]][1],on.$=Pt[Pt.length-An],on._$={first_line:Qe[Qe.length-(An||1)].first_line,last_line:Qe[Qe.length-1].last_line,first_column:Qe[Qe.length-(An||1)].first_column,last_column:Qe[Qe.length-1].last_column},Tr&&(on._$.range=[Qe[Qe.length-(An||1)].range[0],Qe[Qe.length-1].range[1]]),wt=this.performAction.apply(on,[kt,ht,On,Ma.yy,At[1],Pt,Qe].concat(ji)),typeof wt<"u")return wt;An&&(ln=ln.slice(0,-1*An*2),Pt=Pt.slice(0,-1*An),Qe=Qe.slice(0,-1*An)),ln.push(this.productions_[At[1]][0]),Pt.push(on.$),Qe.push(on._$),oo=Dt[ln[ln.length-2]][ln[ln.length-1]],ln.push(oo);break;case 3:return!0}}return!0}},Ne=function(){var _t={EOF:1,parseError:function(Gt,ln){if(this.yy.parser)this.yy.parser.parseError(Gt,ln);else throw new Error(Gt)},setInput:function(Et,Gt){return this.yy=Gt||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},input:function(){var Et=this._input[0];this.yytext+=Et,this.yyleng++,this.offset++,this.match+=Et,this.matched+=Et;var Gt=Et.match(/(?:\r\n?|\n).*/g);return Gt?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Et},unput:function(Et){var Gt=Et.length,ln=Et.split(/(?:\r\n?|\n)/g);this._input=Et+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Gt),this.offset-=Gt;var xt=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),ln.length-1&&(this.yylineno-=ln.length-1);var Pt=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:ln?(ln.length===xt.length?this.yylloc.first_column:0)+xt[xt.length-ln.length].length-ln[0].length:this.yylloc.first_column-Gt},this.options.ranges&&(this.yylloc.range=[Pt[0],Pt[0]+this.yyleng-Gt]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(Et){this.unput(this.match.slice(Et))},pastInput:function(){var Et=this.matched.substr(0,this.matched.length-this.match.length);return(Et.length>20?"...":"")+Et.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var Et=this.pastInput(),Gt=new Array(Et.length+1).join("-");return Et+this.upcomingInput()+` +`+Gt+"^"},test_match:function(Et,Gt){var ln,xt,Pt;if(this.options.backtrack_lexer&&(Pt={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&&(Pt.yylloc.range=this.yylloc.range.slice(0))),xt=Et[0].match(/(?:\r\n?|\n).*/g),xt&&(this.yylineno+=xt.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:xt?xt[xt.length-1].length-xt[xt.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],ln=this.performAction.call(this,this.yy,this,Gt,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ln)return ln;if(this._backtrack){for(var Qe in Pt)this[Qe]=Pt[Qe];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Et,Gt,ln,xt;this._more||(this.yytext="",this.match="");for(var Pt=this._currentRules(),Qe=0;QeGt[0].length)){if(Gt=ln,xt=Qe,this.options.backtrack_lexer){if(Et=this.test_match(ln,Pt[Qe]),Et!==!1)return Et;if(this._backtrack){Gt=!1;continue}else return!1}else if(!this.options.flex)break}return Gt?(Et=this.test_match(Gt,Pt[xt]),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})},lex:function(){var Gt=this.next();return Gt||this.lex()},begin:function(Gt){this.conditionStack.push(Gt)},popState:function(){var Gt=this.conditionStack.length-1;return Gt>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(Gt){return Gt=this.conditionStack.length-1-Math.abs(Gt||0),Gt>=0?this.conditionStack[Gt]:"INITIAL"},pushState:function(Gt){this.begin(Gt)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(Gt,ln,xt,Pt){switch(xt){case 0:return"title";case 1:return this.begin("acc_title"),9;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),11;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 5;case 9:break;case 10:break;case 11:break;case 12:return 8;case 13:return 6;case 14:return 19;case 15:return 30;case 16:return 22;case 17:return 21;case 18:return 24;case 19:return 26;case 20:return 28;case 21:return 31;case 22:return 32;case 23:return 33;case 24:return 34;case 25:return 35;case 26:return 36;case 27:return 37;case 28:return 38;case 29:return 39;case 30:return 40;case 31:return 41;case 32:return 42;case 33:return 43;case 34:return 44;case 35:return 55;case 36:return 56;case 37:return 57;case 38:return 58;case 39:return 59;case 40:return 60;case 41:return 61;case 42:return 47;case 43:return 49;case 44:return 51;case 45:return 54;case 46:return 53;case 47:this.begin("string");break;case 48:this.popState();break;case 49:return"qString";case 50:return ln.yytext=ln.yytext.trim(),62}},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,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/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,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[48,49],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,50],inclusive:!0}}};return _t}();Ft.lexer=Ne;function gn(){this.yy={}}return gn.prototype=Ft,Ft.Parser=gn,new gn}();mve.parser=mve;const lrn=mve;let vve=[],V2={},VR={},F9={},UR={};const hrn={RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},getConfig:()=>qt().req,addRequirement:(i,s)=>(VR[i]===void 0&&(VR[i]={name:i,type:s,id:V2.id,text:V2.text,risk:V2.risk,verifyMethod:V2.verifyMethod}),V2={},VR[i]),getRequirements:()=>VR,setNewReqId:i=>{V2!==void 0&&(V2.id=i)},setNewReqText:i=>{V2!==void 0&&(V2.text=i)},setNewReqRisk:i=>{V2!==void 0&&(V2.risk=i)},setNewReqVerifyMethod:i=>{V2!==void 0&&(V2.verifyMethod=i)},setAccTitle:Bg,getAccTitle:Cp,setAccDescription:Sp,getAccDescription:_p,addElement:i=>(UR[i]===void 0&&(UR[i]={name:i,type:F9.type,docRef:F9.docRef},Xe.info("Added new requirement: ",i)),F9={},UR[i]),getElements:()=>UR,setNewElementType:i=>{F9!==void 0&&(F9.type=i)},setNewElementDocRef:i=>{F9!==void 0&&(F9.docRef=i)},addRelationship:(i,s,u)=>{vve.push({type:i,src:s,dst:u})},getRelationships:()=>vve,clear:()=>{vve=[],V2={},VR={},F9={},UR={},Pg()}},frn=i=>` + + marker { + fill: ${i.relationColor}; + stroke: ${i.relationColor}; + } + + marker.cross { + stroke: ${i.lineColor}; + } + + svg { + font-family: ${i.fontFamily}; + font-size: ${i.fontSize}; + } + + .reqBox { + fill: ${i.requirementBackground}; + fill-opacity: 1.0; + stroke: ${i.requirementBorderColor}; + stroke-width: ${i.requirementBorderSize}; + } + + .reqTitle, .reqLabel{ + fill: ${i.requirementTextColor}; + } + .reqLabelBox { + fill: ${i.relationLabelBackground}; + fill-opacity: 1.0; + } + + .req-title-line { + stroke: ${i.requirementBorderColor}; + stroke-width: ${i.requirementBorderSize}; + } + .relationshipLine { + stroke: ${i.relationColor}; + stroke-width: 1; + } + .relationshipLabel { + fill: ${i.relationLabelColor}; + } + +`,wve={CONTAINS:"contains",ARROW:"arrow"},SGe={ReqMarkers:wve,insertLineEndings:(i,s)=>{let u=i.append("defs").append("marker").attr("id",wve.CONTAINS+"_line_ending").attr("refX",0).attr("refY",s.line_height/2).attr("markerWidth",s.line_height).attr("markerHeight",s.line_height).attr("orient","auto").append("g");u.append("circle").attr("cx",s.line_height/2).attr("cy",s.line_height/2).attr("r",s.line_height/2).attr("fill","none"),u.append("line").attr("x1",0).attr("x2",s.line_height).attr("y1",s.line_height/2).attr("y2",s.line_height/2).attr("stroke-width",1),u.append("line").attr("y1",0).attr("y2",s.line_height).attr("x1",s.line_height/2).attr("x2",s.line_height/2).attr("stroke-width",1),i.append("defs").append("marker").attr("id",wve.ARROW+"_line_ending").attr("refX",s.line_height).attr("refY",.5*s.line_height).attr("markerWidth",s.line_height).attr("markerHeight",s.line_height).attr("orient","auto").append("path").attr("d",`M0,0 + L${s.line_height},${s.line_height/2} + M${s.line_height},${s.line_height/2} + L0,${s.line_height}`).attr("stroke-width",1)}};let Tf={},_Ge=0;const AGe=(i,s)=>i.insert("rect","#"+s).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",Tf.rect_min_width+"px").attr("height",Tf.rect_min_height+"px"),LGe=(i,s,u)=>{let d=Tf.rect_min_width/2,p=i.append("text").attr("class","req reqLabel reqTitle").attr("id",s).attr("x",d).attr("y",Tf.rect_padding).attr("dominant-baseline","hanging"),v=0;u.forEach(_=>{v==0?p.append("tspan").attr("text-anchor","middle").attr("x",Tf.rect_min_width/2).attr("dy",0).text(_):p.append("tspan").attr("text-anchor","middle").attr("x",Tf.rect_min_width/2).attr("dy",Tf.line_height*.75).text(_),v++});let b=1.5*Tf.rect_padding,y=v*Tf.line_height*.75,T=b+y;return i.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",Tf.rect_min_width).attr("y1",T).attr("y2",T),{titleNode:p,y:T}},MGe=(i,s,u,d)=>{let p=i.append("text").attr("class","req reqLabel").attr("id",s).attr("x",Tf.rect_padding).attr("y",d).attr("dominant-baseline","hanging"),v=0;const b=30;let y=[];return u.forEach(T=>{let _=T.length;for(;_>b&&v<3;){let A=T.substring(0,b);T=T.substring(b,T.length),_=T.length,y[y.length]=A,v++}if(v==3){let A=y[y.length-1];y[y.length-1]=A.substring(0,A.length-4)+"..."}else y[y.length]=T;v=0}),y.forEach(T=>{p.append("tspan").attr("x",Tf.rect_padding).attr("dy",Tf.line_height).text(T)}),p},drn=(i,s,u,d)=>{const p=s.node().getTotalLength(),v=s.node().getPointAtLength(p*.5),b="rel"+_Ge;_Ge++;const T=i.append("text").attr("class","req relationshipLabel").attr("id",b).attr("x",v.x).attr("y",v.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(d).node().getBBox();i.insert("rect","#"+b).attr("class","req reqLabelBox").attr("x",v.x-T.width/2).attr("y",v.y-T.height/2).attr("width",T.width).attr("height",T.height).attr("fill","white").attr("fill-opacity","85%")},grn=function(i,s,u,d,p){const v=u.edge(WD(s.src),WD(s.dst)),b=k7().x(function(T){return T.x}).y(function(T){return T.y}),y=i.insert("path","#"+d).attr("class","er relationshipLine").attr("d",b(v.points)).attr("fill","none");s.type==p.db.Relationships.CONTAINS?y.attr("marker-start","url("+ci.getUrl(Tf.arrowMarkerAbsolute)+"#"+s.type+"_line_ending)"):(y.attr("stroke-dasharray","10,7"),y.attr("marker-end","url("+ci.getUrl(Tf.arrowMarkerAbsolute)+"#"+SGe.ReqMarkers.ARROW+"_line_ending)")),drn(i,y,Tf,`<<${s.type}>>`)},prn=(i,s,u)=>{Object.keys(i).forEach(d=>{let p=i[d];d=WD(d),Xe.info("Added new requirement: ",d);const v=u.append("g").attr("id",d),b="req-"+d,y=AGe(v,b);let T=LGe(v,d+"_title",[`<<${p.type}>>`,`${p.name}`]);MGe(v,d+"_body",[`Id: ${p.id}`,`Text: ${p.text}`,`Risk: ${p.risk}`,`Verification: ${p.verifyMethod}`],T.y);const _=y.node().getBBox();s.setNode(d,{width:_.width,height:_.height,shape:"rect",id:d})})},brn=(i,s,u)=>{Object.keys(i).forEach(d=>{let p=i[d];const v=WD(d),b=u.append("g").attr("id",v),y="element-"+v,T=AGe(b,y);let _=LGe(b,y+"_title",["<>",`${d}`]);MGe(b,y+"_body",[`Type: ${p.type||"Not Specified"}`,`Doc Ref: ${p.docRef||"None"}`],_.y);const A=T.node().getBBox();s.setNode(v,{width:A.width,height:A.height,shape:"rect",id:v})})},mrn=(i,s)=>(i.forEach(function(u){let d=WD(u.src),p=WD(u.dst);s.setEdge(d,p,{relationship:u})}),i),vrn=function(i,s){s.nodes().forEach(function(u){u!==void 0&&s.node(u)!==void 0&&(i.select("#"+u),i.select("#"+u).attr("transform","translate("+(s.node(u).x-s.node(u).width/2)+","+(s.node(u).y-s.node(u).height/2)+" )"))})},WD=i=>i.replace(/\s/g,"").replace(/\./g,"_"),wrn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:lrn,db:hrn,renderer:{draw:(i,s,u,d)=>{Tf=qt().requirement;const p=Tf.securityLevel;let v;p==="sandbox"&&(v=Ir("#i"+s));const y=Ir(p==="sandbox"?v.nodes()[0].contentDocument.body:"body").select(`[id='${s}']`);SGe.insertLineEndings(y,Tf);const T=new B0({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:Tf.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel(function(){return{}});let _=d.db.getRequirements(),A=d.db.getElements(),P=d.db.getRelationships();prn(_,T,y),brn(A,T,y),mrn(P,T),qD(T),vrn(y,T),P.forEach(function(ee){grn(y,ee,T,s,d)});const R=Tf.rect_padding,F=y.node().getBBox(),j=F.width+R*2,K=F.height+R*2;Ng(y,K,j,Tf.useMaxWidth),y.attr("viewBox",`${F.x-R} ${F.y-R} ${j} ${K}`)}},styles:frn}},Symbol.toStringTag,{value:"Module"}));var yve=function(){var i=function(xt,Pt,Qe,Dt){for(Qe=Qe||{},Dt=xt.length;Dt--;Qe[xt[Dt]]=Pt);return Qe},s=[1,2],u=[1,3],d=[1,4],p=[2,4],v=[1,9],b=[1,11],y=[1,13],T=[1,14],_=[1,16],A=[1,17],P=[1,18],R=[1,24],F=[1,25],j=[1,26],K=[1,27],ee=[1,28],ie=[1,29],oe=[1,30],pe=[1,31],be=[1,32],ae=[1,33],ne=[1,34],se=[1,35],de=[1,36],X=[1,37],ge=[1,38],W=[1,39],xe=[1,41],U=[1,42],Fe=[1,43],Pe=[1,44],je=[1,45],Ie=[1,46],Se=[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],Ce=[4,5,16,50,52,53],ke=[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],Ke=[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],Ft=[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],Ne=[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],gn=[68,69,70],_t=[1,120],Et={trace:function(){},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,DOTTED_ARROW:74,SOLID_CROSS:75,DOTTED_CROSS:76,SOLID_POINT:77,DOTTED_POINT:78,TXT:79,$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:"DOTTED_ARROW",75:"SOLID_CROSS",76:"DOTTED_CROSS",77:"SOLID_POINT",78:"DOTTED_POINT",79:"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],[56,1]],performAction:function(Pt,Qe,Dt,kt,On,ht,zr){var yt=ht.length-1;switch(On){case 3:return kt.apply(ht[yt]),ht[yt];case 4:case 9:this.$=[];break;case 5:case 10:ht[yt-1].push(ht[yt]),this.$=ht[yt-1];break;case 6:case 7:case 11:case 12:this.$=ht[yt];break;case 8:case 13:this.$=[];break;case 15:ht[yt].type="createParticipant",this.$=ht[yt];break;case 16:ht[yt-1].unshift({type:"boxStart",boxData:kt.parseBoxData(ht[yt-2])}),ht[yt-1].push({type:"boxEnd",boxText:ht[yt-2]}),this.$=ht[yt-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(ht[yt-2]),sequenceIndexStep:Number(ht[yt-1]),sequenceVisible:!0,signalType:kt.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(ht[yt-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:kt.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:kt.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:kt.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:kt.LINETYPE.ACTIVE_START,actor:ht[yt-1]};break;case 23:this.$={type:"activeEnd",signalType:kt.LINETYPE.ACTIVE_END,actor:ht[yt-1]};break;case 29:kt.setDiagramTitle(ht[yt].substring(6)),this.$=ht[yt].substring(6);break;case 30:kt.setDiagramTitle(ht[yt].substring(7)),this.$=ht[yt].substring(7);break;case 31:this.$=ht[yt].trim(),kt.setAccTitle(this.$);break;case 32:case 33:this.$=ht[yt].trim(),kt.setAccDescription(this.$);break;case 34:ht[yt-1].unshift({type:"loopStart",loopText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.LOOP_START}),ht[yt-1].push({type:"loopEnd",loopText:ht[yt-2],signalType:kt.LINETYPE.LOOP_END}),this.$=ht[yt-1];break;case 35:ht[yt-1].unshift({type:"rectStart",color:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.RECT_START}),ht[yt-1].push({type:"rectEnd",color:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.RECT_END}),this.$=ht[yt-1];break;case 36:ht[yt-1].unshift({type:"optStart",optText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.OPT_START}),ht[yt-1].push({type:"optEnd",optText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.OPT_END}),this.$=ht[yt-1];break;case 37:ht[yt-1].unshift({type:"altStart",altText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.ALT_START}),ht[yt-1].push({type:"altEnd",signalType:kt.LINETYPE.ALT_END}),this.$=ht[yt-1];break;case 38:ht[yt-1].unshift({type:"parStart",parText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.PAR_START}),ht[yt-1].push({type:"parEnd",signalType:kt.LINETYPE.PAR_END}),this.$=ht[yt-1];break;case 39:ht[yt-1].unshift({type:"parStart",parText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.PAR_OVER_START}),ht[yt-1].push({type:"parEnd",signalType:kt.LINETYPE.PAR_END}),this.$=ht[yt-1];break;case 40:ht[yt-1].unshift({type:"criticalStart",criticalText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.CRITICAL_START}),ht[yt-1].push({type:"criticalEnd",signalType:kt.LINETYPE.CRITICAL_END}),this.$=ht[yt-1];break;case 41:ht[yt-1].unshift({type:"breakStart",breakText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.BREAK_START}),ht[yt-1].push({type:"breakEnd",optText:kt.parseMessage(ht[yt-2]),signalType:kt.LINETYPE.BREAK_END}),this.$=ht[yt-1];break;case 43:this.$=ht[yt-3].concat([{type:"option",optionText:kt.parseMessage(ht[yt-1]),signalType:kt.LINETYPE.CRITICAL_OPTION},ht[yt]]);break;case 45:this.$=ht[yt-3].concat([{type:"and",parText:kt.parseMessage(ht[yt-1]),signalType:kt.LINETYPE.PAR_AND},ht[yt]]);break;case 47:this.$=ht[yt-3].concat([{type:"else",altText:kt.parseMessage(ht[yt-1]),signalType:kt.LINETYPE.ALT_ELSE},ht[yt]]);break;case 48:ht[yt-3].draw="participant",ht[yt-3].type="addParticipant",ht[yt-3].description=kt.parseMessage(ht[yt-1]),this.$=ht[yt-3];break;case 49:ht[yt-1].draw="participant",ht[yt-1].type="addParticipant",this.$=ht[yt-1];break;case 50:ht[yt-3].draw="actor",ht[yt-3].type="addParticipant",ht[yt-3].description=kt.parseMessage(ht[yt-1]),this.$=ht[yt-3];break;case 51:ht[yt-1].draw="actor",ht[yt-1].type="addParticipant",this.$=ht[yt-1];break;case 52:ht[yt-1].type="destroyParticipant",this.$=ht[yt-1];break;case 53:this.$=[ht[yt-1],{type:"addNote",placement:ht[yt-2],actor:ht[yt-1].actor,text:ht[yt]}];break;case 54:ht[yt-2]=[].concat(ht[yt-1],ht[yt-1]).slice(0,2),ht[yt-2][0]=ht[yt-2][0].actor,ht[yt-2][1]=ht[yt-2][1].actor,this.$=[ht[yt-1],{type:"addNote",placement:kt.PLACEMENT.OVER,actor:ht[yt-2].slice(0,2),text:ht[yt]}];break;case 55:this.$=[ht[yt-1],{type:"addLinks",actor:ht[yt-1].actor,text:ht[yt]}];break;case 56:this.$=[ht[yt-1],{type:"addALink",actor:ht[yt-1].actor,text:ht[yt]}];break;case 57:this.$=[ht[yt-1],{type:"addProperties",actor:ht[yt-1].actor,text:ht[yt]}];break;case 58:this.$=[ht[yt-1],{type:"addDetails",actor:ht[yt-1].actor,text:ht[yt]}];break;case 61:this.$=[ht[yt-2],ht[yt]];break;case 62:this.$=ht[yt];break;case 63:this.$=kt.PLACEMENT.LEFTOF;break;case 64:this.$=kt.PLACEMENT.RIGHTOF;break;case 65:this.$=[ht[yt-4],ht[yt-1],{type:"addMessage",from:ht[yt-4].actor,to:ht[yt-1].actor,signalType:ht[yt-3],msg:ht[yt],activate:!0},{type:"activeStart",signalType:kt.LINETYPE.ACTIVE_START,actor:ht[yt-1]}];break;case 66:this.$=[ht[yt-4],ht[yt-1],{type:"addMessage",from:ht[yt-4].actor,to:ht[yt-1].actor,signalType:ht[yt-3],msg:ht[yt]},{type:"activeEnd",signalType:kt.LINETYPE.ACTIVE_END,actor:ht[yt-4]}];break;case 67:this.$=[ht[yt-3],ht[yt-1],{type:"addMessage",from:ht[yt-3].actor,to:ht[yt-1].actor,signalType:ht[yt-2],msg:ht[yt]}];break;case 68:this.$={type:"addParticipant",actor:ht[yt]};break;case 69:this.$=kt.LINETYPE.SOLID_OPEN;break;case 70:this.$=kt.LINETYPE.DOTTED_OPEN;break;case 71:this.$=kt.LINETYPE.SOLID;break;case 72:this.$=kt.LINETYPE.DOTTED;break;case 73:this.$=kt.LINETYPE.SOLID_CROSS;break;case 74:this.$=kt.LINETYPE.DOTTED_CROSS;break;case 75:this.$=kt.LINETYPE.SOLID_POINT;break;case 76:this.$=kt.LINETYPE.DOTTED_POINT;break;case 77:this.$=kt.parseMessage(ht[yt].trim().substring(1));break}},table:[{3:1,4:s,5:u,6:d},{1:[3]},{3:5,4:s,5:u,6:d},{3:6,4:s,5:u,6:d},i([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],p,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:v,5:b,8:8,9:10,12:12,13:y,14:T,17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},i(Se,[2,5]),{9:47,12:12,13:y,14:T,17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},i(Se,[2,7]),i(Se,[2,8]),i(Se,[2,14]),{12:48,50:X,52:ge,53:W},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:Ie},{22:55,70:Ie},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},i(Se,[2,29]),i(Se,[2,30]),{32:[1,61]},{34:[1,62]},i(Se,[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:Ie},{22:72,70:Ie},{22:73,70:Ie},{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]},{55:83,57:[1,84],65:[1,85],66:[1,86]},{22:87,70:Ie},{22:88,70:Ie},{22:89,70:Ie},{22:90,70:Ie},i([5,51,64,71,72,73,74,75,76,77,78,79],[2,68]),i(Se,[2,6]),i(Se,[2,15]),i(Ce,[2,9],{10:91}),i(Se,[2,17]),{5:[1,93],19:[1,92]},{5:[1,94]},i(Se,[2,21]),{5:[1,95]},{5:[1,96]},i(Se,[2,24]),i(Se,[2,25]),i(Se,[2,26]),i(Se,[2,27]),i(Se,[2,28]),i(Se,[2,31]),i(Se,[2,32]),i(ke,p,{7:97}),i(ke,p,{7:98}),i(ke,p,{7:99}),i(Ke,p,{40:100,7:101}),i(Ft,p,{42:102,7:103}),i(Ft,p,{7:103,42:104}),i(Ne,p,{45:105,7:106}),i(ke,p,{7:107}),{5:[1,109],51:[1,108]},{5:[1,111],51:[1,110]},{5:[1,112]},{22:115,68:[1,113],69:[1,114],70:Ie},i(gn,[2,69]),i(gn,[2,70]),i(gn,[2,71]),i(gn,[2,72]),i(gn,[2,73]),i(gn,[2,74]),i(gn,[2,75]),i(gn,[2,76]),{22:116,70:Ie},{22:118,58:117,70:Ie},{70:[2,63]},{70:[2,64]},{56:119,79:_t},{56:121,79:_t},{56:122,79:_t},{56:123,79:_t},{4:[1,126],5:[1,128],11:125,12:127,16:[1,124],50:X,52:ge,53:W},{5:[1,129]},i(Se,[2,19]),i(Se,[2,20]),i(Se,[2,22]),i(Se,[2,23]),{4:v,5:b,8:8,9:10,12:12,13:y,14:T,16:[1,130],17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},{4:v,5:b,8:8,9:10,12:12,13:y,14:T,16:[1,131],17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},{4:v,5:b,8:8,9:10,12:12,13:y,14:T,16:[1,132],17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},{16:[1,133]},{4:v,5:b,8:8,9:10,12:12,13:y,14:T,16:[2,46],17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,49:[1,134],50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},{16:[1,135]},{4:v,5:b,8:8,9:10,12:12,13:y,14:T,16:[2,44],17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,48:[1,136],50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},{16:[1,137]},{16:[1,138]},{4:v,5:b,8:8,9:10,12:12,13:y,14:T,16:[2,42],17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,47:[1,139],50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},{4:v,5:b,8:8,9:10,12:12,13:y,14:T,16:[1,140],17:15,18:_,21:A,22:40,23:P,24:19,25:20,26:21,27:22,28:23,29:R,30:F,31:j,33:K,35:ee,36:ie,37:oe,38:pe,39:be,41:ae,43:ne,44:se,46:de,50:X,52:ge,53:W,54:xe,59:U,60:Fe,61:Pe,62:je,70:Ie},{15:[1,141]},i(Se,[2,49]),{15:[1,142]},i(Se,[2,51]),i(Se,[2,52]),{22:143,70:Ie},{22:144,70:Ie},{56:145,79:_t},{56:146,79:_t},{56:147,79:_t},{64:[1,148],79:[2,62]},{5:[2,55]},{5:[2,77]},{5:[2,56]},{5:[2,57]},{5:[2,58]},i(Se,[2,16]),i(Ce,[2,10]),{12:149,50:X,52:ge,53:W},i(Ce,[2,12]),i(Ce,[2,13]),i(Se,[2,18]),i(Se,[2,34]),i(Se,[2,35]),i(Se,[2,36]),i(Se,[2,37]),{15:[1,150]},i(Se,[2,38]),{15:[1,151]},i(Se,[2,39]),i(Se,[2,40]),{15:[1,152]},i(Se,[2,41]),{5:[1,153]},{5:[1,154]},{56:155,79:_t},{56:156,79:_t},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:157,70:Ie},i(Ce,[2,11]),i(Ke,p,{7:101,40:158}),i(Ft,p,{7:103,42:159}),i(Ne,p,{7:106,45:160}),i(Se,[2,48]),i(Se,[2,50]),{5:[2,65]},{5:[2,66]},{79:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],85:[2,63],86:[2,64],119:[2,55],120:[2,77],121:[2,56],122:[2,57],123:[2,58],145:[2,67],146:[2,53],147:[2,54],155:[2,65],156:[2,66],157:[2,61],158:[2,47],159:[2,45],160:[2,43]},parseError:function(Pt,Qe){if(Qe.recoverable)this.trace(Pt);else{var Dt=new Error(Pt);throw Dt.hash=Qe,Dt}},parse:function(Pt){var Qe=this,Dt=[0],kt=[],On=[null],ht=[],zr=this.table,yt="",ji=0,xi=0,Ma=2,zs=1,ao=ht.slice.call(arguments,1),Tr=Object.create(this.lexer),Fn={yy:{}};for(var qn in this.yy)Object.prototype.hasOwnProperty.call(this.yy,qn)&&(Fn.yy[qn]=this.yy[qn]);Tr.setInput(Pt,Fn.yy),Fn.yy.lexer=Tr,Fn.yy.parser=this,typeof Tr.yylloc>"u"&&(Tr.yylloc={});var Un=Tr.yylloc;ht.push(Un);var At=Tr.options&&Tr.options.ranges;typeof Fn.yy.parseError=="function"?this.parseError=Fn.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function wt(){var da;return da=kt.pop()||Tr.lex()||zs,typeof da!="number"&&(da instanceof Array&&(kt=da,da=kt.pop()),da=Qe.symbols_[da]||da),da}for(var on,fn,An,oo,jo={},$o,Pa,wo,_s;;){if(fn=Dt[Dt.length-1],this.defaultActions[fn]?An=this.defaultActions[fn]:((on===null||typeof on>"u")&&(on=wt()),An=zr[fn]&&zr[fn][on]),typeof An>"u"||!An.length||!An[0]){var tl="";_s=[];for($o in zr[fn])this.terminals_[$o]&&$o>Ma&&_s.push("'"+this.terminals_[$o]+"'");Tr.showPosition?tl="Parse error on line "+(ji+1)+`: +`+Tr.showPosition()+` +Expecting `+_s.join(", ")+", got '"+(this.terminals_[on]||on)+"'":tl="Parse error on line "+(ji+1)+": Unexpected "+(on==zs?"end of input":"'"+(this.terminals_[on]||on)+"'"),this.parseError(tl,{text:Tr.match,token:this.terminals_[on]||on,line:Tr.yylineno,loc:Un,expected:_s})}if(An[0]instanceof Array&&An.length>1)throw new Error("Parse Error: multiple actions possible at state: "+fn+", token: "+on);switch(An[0]){case 1:Dt.push(on),On.push(Tr.yytext),ht.push(Tr.yylloc),Dt.push(An[1]),on=null,xi=Tr.yyleng,yt=Tr.yytext,ji=Tr.yylineno,Un=Tr.yylloc;break;case 2:if(Pa=this.productions_[An[1]][1],jo.$=On[On.length-Pa],jo._$={first_line:ht[ht.length-(Pa||1)].first_line,last_line:ht[ht.length-1].last_line,first_column:ht[ht.length-(Pa||1)].first_column,last_column:ht[ht.length-1].last_column},At&&(jo._$.range=[ht[ht.length-(Pa||1)].range[0],ht[ht.length-1].range[1]]),oo=this.performAction.apply(jo,[yt,xi,ji,Fn.yy,An[1],On,ht].concat(ao)),typeof oo<"u")return oo;Pa&&(Dt=Dt.slice(0,-1*Pa*2),On=On.slice(0,-1*Pa),ht=ht.slice(0,-1*Pa)),Dt.push(this.productions_[An[1]][0]),On.push(jo.$),ht.push(jo._$),wo=zr[Dt[Dt.length-2]][Dt[Dt.length-1]],Dt.push(wo);break;case 3:return!0}}return!0}},Gt=function(){var xt={EOF:1,parseError:function(Qe,Dt){if(this.yy.parser)this.yy.parser.parseError(Qe,Dt);else throw new Error(Qe)},setInput:function(Pt,Qe){return this.yy=Qe||this.yy||{},this._input=Pt,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},input:function(){var Pt=this._input[0];this.yytext+=Pt,this.yyleng++,this.offset++,this.match+=Pt,this.matched+=Pt;var Qe=Pt.match(/(?:\r\n?|\n).*/g);return Qe?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Pt},unput:function(Pt){var Qe=Pt.length,Dt=Pt.split(/(?:\r\n?|\n)/g);this._input=Pt+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Qe),this.offset-=Qe;var kt=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),Dt.length-1&&(this.yylineno-=Dt.length-1);var On=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:Dt?(Dt.length===kt.length?this.yylloc.first_column:0)+kt[kt.length-Dt.length].length-Dt[0].length:this.yylloc.first_column-Qe},this.options.ranges&&(this.yylloc.range=[On[0],On[0]+this.yyleng-Qe]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(Pt){this.unput(this.match.slice(Pt))},pastInput:function(){var Pt=this.matched.substr(0,this.matched.length-this.match.length);return(Pt.length>20?"...":"")+Pt.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var Pt=this.match;return Pt.length<20&&(Pt+=this._input.substr(0,20-Pt.length)),(Pt.substr(0,20)+(Pt.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var Pt=this.pastInput(),Qe=new Array(Pt.length+1).join("-");return Pt+this.upcomingInput()+` +`+Qe+"^"},test_match:function(Pt,Qe){var Dt,kt,On;if(this.options.backtrack_lexer&&(On={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&&(On.yylloc.range=this.yylloc.range.slice(0))),kt=Pt[0].match(/(?:\r\n?|\n).*/g),kt&&(this.yylineno+=kt.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:kt?kt[kt.length-1].length-kt[kt.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+Pt[0].length},this.yytext+=Pt[0],this.match+=Pt[0],this.matches=Pt,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(Pt[0].length),this.matched+=Pt[0],Dt=this.performAction.call(this,this.yy,this,Qe,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Dt)return Dt;if(this._backtrack){for(var ht in On)this[ht]=On[ht];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Pt,Qe,Dt,kt;this._more||(this.yytext="",this.match="");for(var On=this._currentRules(),ht=0;htQe[0].length)){if(Qe=Dt,kt=ht,this.options.backtrack_lexer){if(Pt=this.test_match(Dt,On[ht]),Pt!==!1)return Pt;if(this._backtrack){Qe=!1;continue}else return!1}else if(!this.options.flex)break}return Qe?(Pt=this.test_match(Qe,On[kt]),Pt!==!1?Pt:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var Qe=this.next();return Qe||this.lex()},begin:function(Qe){this.conditionStack.push(Qe)},popState:function(){var Qe=this.conditionStack.length-1;return Qe>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(Qe){return Qe=this.conditionStack.length-1-Math.abs(Qe||0),Qe>=0?this.conditionStack[Qe]:"INITIAL"},pushState:function(Qe){this.begin(Qe)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(Qe,Dt,kt,On){switch(kt){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;case 8:return this.begin("ID"),50;case 9:return this.begin("ID"),52;case 10:return 13;case 11:return this.begin("ID"),53;case 12:return Dt.yytext=Dt.yytext.trim(),this.begin("ALIAS"),70;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;case 14:return this.popState(),this.popState(),5;case 15:return this.begin("LINE"),36;case 16:return this.begin("LINE"),37;case 17:return this.begin("LINE"),38;case 18:return this.begin("LINE"),39;case 19:return this.begin("LINE"),49;case 20:return this.begin("LINE"),41;case 21:return this.begin("LINE"),43;case 22:return this.begin("LINE"),48;case 23:return this.begin("LINE"),44;case 24:return this.begin("LINE"),47;case 25:return this.begin("LINE"),46;case 26:return this.popState(),15;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;case 37:return this.begin("ID"),23;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;case 41:return this.popState(),"acc_title_value";case 42:return this.begin("acc_descr"),33;case 43:return this.popState(),"acc_descr_value";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 Dt.yytext=Dt.yytext.trim(),70;case 53:return 73;case 54:return 74;case 55:return 71;case 56:return 72;case 57:return 75;case 58:return 76;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 68;case 63:return 69;case 64:return 5;case 65:return"INVALID"}},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,/^(?:-[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],inclusive:!0}}};return xt}();Et.lexer=Gt;function ln(){this.yy={}}return ln.prototype=Et,Et.Parser=ln,new ln}();yve.parser=yve;const yrn=yve;class xrn{constructor(s){this.init=s,this.records=this.init()}reset(){this.records=this.init()}}const Ds=new xrn(()=>({prevActor:void 0,actors:{},createdActors:{},destroyedActors:{},boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0})),krn=function(i){Ds.records.boxes.push({name:i.text,wrap:i.wrap===void 0&&JC()||!!i.wrap,fill:i.color,actorKeys:[]}),Ds.records.currentBox=Ds.records.boxes.slice(-1)[0]},xve=function(i,s,u,d){let p=Ds.records.currentBox;const v=Ds.records.actors[i];if(v){if(Ds.records.currentBox&&v.box&&Ds.records.currentBox!==v.box)throw new Error("A same participant should only be defined in one Box: "+v.name+" can't be in '"+v.box.name+"' and in '"+Ds.records.currentBox.name+"' at the same time.");if(p=v.box?v.box:Ds.records.currentBox,v.box=p,v&&s===v.name&&u==null)return}(u==null||u.text==null)&&(u={text:s,wrap:null,type:d}),(d==null||u.text==null)&&(u={text:s,wrap:null,type:d}),Ds.records.actors[i]={box:p,name:s,description:u.text,wrap:u.wrap===void 0&&JC()||!!u.wrap,prevActor:Ds.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:d||"participant"},Ds.records.prevActor&&Ds.records.actors[Ds.records.prevActor]&&(Ds.records.actors[Ds.records.prevActor].nextActor=i),Ds.records.currentBox&&Ds.records.currentBox.actorKeys.push(i),Ds.records.prevActor=i},Ern=i=>{let s,u=0;for(s=0;s>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},b}return Ds.records.messages.push({from:i,to:s,message:u.text,wrap:u.wrap===void 0&&JC()||!!u.wrap,type:d,activate:p}),!0},Crn=function(){return Ds.records.boxes.length>0},Srn=function(){return Ds.records.boxes.some(i=>i.name)},_rn=function(){return Ds.records.messages},Arn=function(){return Ds.records.boxes},Lrn=function(){return Ds.records.actors},Mrn=function(){return Ds.records.createdActors},Drn=function(){return Ds.records.destroyedActors},GR=function(i){return Ds.records.actors[i]},Irn=function(){return Object.keys(Ds.records.actors)},Orn=function(){Ds.records.sequenceNumbersEnabled=!0},Nrn=function(){Ds.records.sequenceNumbersEnabled=!1},Prn=()=>Ds.records.sequenceNumbersEnabled,Brn=function(i){Ds.records.wrapEnabled=i},JC=()=>Ds.records.wrapEnabled!==void 0?Ds.records.wrapEnabled:qt().sequence.wrap,Frn=function(){Ds.reset(),Pg()},Rrn=function(i){const s=i.trim(),u={text:s.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:s.match(/^:?wrap:/)!==null?!0:s.match(/^:?nowrap:/)!==null?!1:void 0};return Xe.debug("parseMessage:",u),u},jrn=function(i){const s=i.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);let u=s!=null&&s[1]?s[1].trim():"transparent",d=s!=null&&s[2]?s[2].trim():void 0;if(window&&window.CSS)window.CSS.supports("color",u)||(u="transparent",d=i.trim());else{const p=new Option().style;p.color=u,p.color!==u&&(u="transparent",d=i.trim())}return{color:u,text:d!==void 0?Yf(d.replace(/^:?(?:no)?wrap:/,""),qt()):void 0,wrap:d!==void 0?d.match(/^:?wrap:/)!==null?!0:d.match(/^:?nowrap:/)!==null?!1:void 0:void 0}},KR={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},$rn={FILLED:0,OPEN:1},zrn={LEFTOF:0,RIGHTOF:1,OVER:2},DGe=function(i,s,u){const d={actor:i,placement:s,message:u.text,wrap:u.wrap===void 0&&JC()||!!u.wrap},p=[].concat(i,i);Ds.records.notes.push(d),Ds.records.messages.push({from:p[0],to:p[1],message:u.text,wrap:u.wrap===void 0&&JC()||!!u.wrap,type:KR.NOTE,placement:s})},IGe=function(i,s){const u=GR(i);try{let d=Yf(s.text,qt());d=d.replace(/&/g,"&"),d=d.replace(/=/g,"=");const p=JSON.parse(d);kve(u,p)}catch(d){Xe.error("error while parsing actor link text",d)}},qrn=function(i,s){const u=GR(i);try{const b={};let y=Yf(s.text,qt());var d=y.indexOf("@");y=y.replace(/&/g,"&"),y=y.replace(/=/g,"=");var p=y.slice(0,d-1).trim(),v=y.slice(d+1).trim();b[p]=v,kve(u,b)}catch(b){Xe.error("error while parsing actor link text",b)}};function kve(i,s){if(i.links==null)i.links=s;else for(let u in s)i.links[u]=s[u]}const OGe=function(i,s){const u=GR(i);try{let d=Yf(s.text,qt());const p=JSON.parse(d);NGe(u,p)}catch(d){Xe.error("error while parsing actor properties text",d)}};function NGe(i,s){if(i.properties==null)i.properties=s;else for(let u in s)i.properties[u]=s[u]}function Hrn(){Ds.records.currentBox=void 0}const PGe=function(i,s){const u=GR(i),d=document.getElementById(s.text);try{const p=d.innerHTML,v=JSON.parse(p);v.properties&&NGe(u,v.properties),v.links&&kve(u,v.links)}catch(p){Xe.error("error while parsing actor details text",p)}},Vrn=function(i,s){if(i!==void 0&&i.properties!==void 0)return i.properties[s]},BGe=function(i){if(Array.isArray(i))i.forEach(function(s){BGe(s)});else switch(i.type){case"sequenceIndex":Ds.records.messages.push({from:void 0,to:void 0,message:{start:i.sequenceIndex,step:i.sequenceIndexStep,visible:i.sequenceVisible},wrap:!1,type:i.signalType});break;case"addParticipant":xve(i.actor,i.actor,i.description,i.draw);break;case"createParticipant":if(Ds.records.actors[i.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");Ds.records.lastCreated=i.actor,xve(i.actor,i.actor,i.description,i.draw),Ds.records.createdActors[i.actor]=Ds.records.messages.length;break;case"destroyParticipant":Ds.records.lastDestroyed=i.actor,Ds.records.destroyedActors[i.actor]=Ds.records.messages.length;break;case"activeStart":Jf(i.actor,void 0,void 0,i.signalType);break;case"activeEnd":Jf(i.actor,void 0,void 0,i.signalType);break;case"addNote":DGe(i.actor,i.placement,i.text);break;case"addLinks":IGe(i.actor,i.text);break;case"addALink":qrn(i.actor,i.text);break;case"addProperties":OGe(i.actor,i.text);break;case"addDetails":PGe(i.actor,i.text);break;case"addMessage":if(Ds.records.lastCreated){if(i.to!==Ds.records.lastCreated)throw new Error("The created participant "+Ds.records.lastCreated+" does not have an associated creating message after its declaration. Please check the sequence diagram.");Ds.records.lastCreated=void 0}else if(Ds.records.lastDestroyed){if(i.to!==Ds.records.lastDestroyed&&i.from!==Ds.records.lastDestroyed)throw new Error("The destroyed participant "+Ds.records.lastDestroyed+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");Ds.records.lastDestroyed=void 0}Jf(i.from,i.to,i.msg,i.signalType,i.activate);break;case"boxStart":krn(i.boxData);break;case"boxEnd":Hrn();break;case"loopStart":Jf(void 0,void 0,i.loopText,i.signalType);break;case"loopEnd":Jf(void 0,void 0,void 0,i.signalType);break;case"rectStart":Jf(void 0,void 0,i.color,i.signalType);break;case"rectEnd":Jf(void 0,void 0,void 0,i.signalType);break;case"optStart":Jf(void 0,void 0,i.optText,i.signalType);break;case"optEnd":Jf(void 0,void 0,void 0,i.signalType);break;case"altStart":Jf(void 0,void 0,i.altText,i.signalType);break;case"else":Jf(void 0,void 0,i.altText,i.signalType);break;case"altEnd":Jf(void 0,void 0,void 0,i.signalType);break;case"setAccTitle":Bg(i.text);break;case"parStart":Jf(void 0,void 0,i.parText,i.signalType);break;case"and":Jf(void 0,void 0,i.parText,i.signalType);break;case"parEnd":Jf(void 0,void 0,void 0,i.signalType);break;case"criticalStart":Jf(void 0,void 0,i.criticalText,i.signalType);break;case"option":Jf(void 0,void 0,i.optionText,i.signalType);break;case"criticalEnd":Jf(void 0,void 0,void 0,i.signalType);break;case"breakStart":Jf(void 0,void 0,i.breakText,i.signalType);break;case"breakEnd":Jf(void 0,void 0,void 0,i.signalType);break}},FGe={addActor:xve,addMessage:Trn,addSignal:Jf,addLinks:IGe,addDetails:PGe,addProperties:OGe,autoWrap:JC,setWrap:Brn,enableSequenceNumbers:Orn,disableSequenceNumbers:Nrn,showSequenceNumbers:Prn,getMessages:_rn,getActors:Lrn,getCreatedActors:Mrn,getDestroyedActors:Drn,getActor:GR,getActorKeys:Irn,getActorProperty:Vrn,getAccTitle:Cp,getBoxes:Arn,getDiagramTitle:Ap,setDiagramTitle:cm,getConfig:()=>qt().sequence,clear:Frn,parseMessage:Rrn,parseBoxData:jrn,LINETYPE:KR,ARROWTYPE:$rn,PLACEMENT:zrn,addNote:DGe,setAccTitle:Bg,apply:BGe,setAccDescription:Sp,getAccDescription:_p,hasAtLeastOneBox:Crn,hasAtLeastOneBoxWithTitle:Srn},Urn=i=>`.actor { + stroke: ${i.actorBorder}; + fill: ${i.actorBkg}; + } + + text.actor > tspan { + fill: ${i.actorTextColor}; + stroke: none; + } + + .actor-line { + stroke: ${i.actorLineColor}; + } + + .messageLine0 { + stroke-width: 1.5; + stroke-dasharray: none; + stroke: ${i.signalColor}; + } + + .messageLine1 { + stroke-width: 1.5; + stroke-dasharray: 2, 2; + stroke: ${i.signalColor}; + } + + #arrowhead path { + fill: ${i.signalColor}; + stroke: ${i.signalColor}; + } + + .sequenceNumber { + fill: ${i.sequenceNumberColor}; + } + + #sequencenumber { + fill: ${i.signalColor}; + } + + #crosshead path { + fill: ${i.signalColor}; + stroke: ${i.signalColor}; + } + + .messageText { + fill: ${i.signalTextColor}; + stroke: none; + } + + .labelBox { + stroke: ${i.labelBoxBorderColor}; + fill: ${i.labelBoxBkgColor}; + } + + .labelText, .labelText > tspan { + fill: ${i.labelTextColor}; + stroke: none; + } + + .loopText, .loopText > tspan { + fill: ${i.loopTextColor}; + stroke: none; + } + + .loopLine { + stroke-width: 2px; + stroke-dasharray: 2, 2; + stroke: ${i.labelBoxBorderColor}; + fill: ${i.labelBoxBorderColor}; + } + + .note { + //stroke: #decc93; + stroke: ${i.noteBorderColor}; + fill: ${i.noteBkgColor}; + } + + .noteText, .noteText > tspan { + fill: ${i.noteTextColor}; + stroke: none; + } + + .activation0 { + fill: ${i.activationBkgColor}; + stroke: ${i.activationBorderColor}; + } + + .activation1 { + fill: ${i.activationBkgColor}; + stroke: ${i.activationBorderColor}; + } + + .activation2 { + fill: ${i.activationBkgColor}; + stroke: ${i.activationBorderColor}; + } + + .actorPopupMenu { + position: absolute; + } + + .actorPopupMenuPanel { + position: absolute; + fill: ${i.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: ${i.actorBorder}; + fill: ${i.actorBkg}; + } + .actor-man circle, line { + stroke: ${i.actorBorder}; + fill: ${i.actorBkg}; + stroke-width: 2px; + } +`,ZC=18*2,RGe="actor-top",jGe="actor-bottom",Eve=function(i,s){return AQ(i,s)},Grn=function(i,s,u,d,p){if(s.links===void 0||s.links===null||Object.keys(s.links).length===0)return{height:0,width:0};const v=s.links,b=s.actorCnt,y=s.rectData;var T="none";p&&(T="block !important");const _=i.append("g");_.attr("id","actor"+b+"_popup"),_.attr("class","actorPopupMenu"),_.attr("display",T);var A="";y.class!==void 0&&(A=" "+y.class);let P=y.width>u?y.width:u;const R=_.append("rect");if(R.attr("class","actorPopupMenuPanel"+A),R.attr("x",y.x),R.attr("y",y.height),R.attr("fill",y.fill),R.attr("stroke",y.stroke),R.attr("width",P),R.attr("height",y.height),R.attr("rx",y.rx),R.attr("ry",y.ry),v!=null){var F=20;for(let ee in v){var j=_.append("a"),K=p9.sanitizeUrl(v[ee]);j.attr("xlink:href",K),j.attr("target","_blank"),uin(d)(ee,j,y.x+10,y.height+F,P,20,{class:"actor"},d),F+=30}}return R.attr("height",F),{height:y.height+F,width:P}},Krn=function(i){return"var pu = document.getElementById('"+i+"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"},pJ=async function(i,s,u=null){let d=i.append("foreignObject");const p=await CC(s.text,Vh()),b=d.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(p).node().getBoundingClientRect();if(d.attr("height",Math.round(b.height)).attr("width",Math.round(b.width)),s.class==="noteText"){const y=i.node().firstChild;y.setAttribute("height",b.height+2*s.textMargin);const T=y.getBBox();d.attr("x",Math.round(T.x+T.width/2-b.width/2)).attr("y",Math.round(T.y+T.height/2-b.height/2))}else if(u){let{startx:y,stopx:T,starty:_}=u;if(y>T){const A=y;y=T,T=A}d.attr("x",Math.round(y+Math.abs(y-T)/2-b.width/2)),s.class==="loopText"?d.attr("y",Math.round(_)):d.attr("y",Math.round(_-b.height))}return[d]},YD=function(i,s){let u=0,d=0;const p=s.text.split(ci.lineBreakRegex),[v,b]=NC(s.fontSize);let y=[],T=0,_=()=>s.y;if(s.valign!==void 0&&s.textMargin!==void 0&&s.textMargin>0)switch(s.valign){case"top":case"start":_=()=>Math.round(s.y+s.textMargin);break;case"middle":case"center":_=()=>Math.round(s.y+(u+d+s.textMargin)/2);break;case"bottom":case"end":_=()=>Math.round(s.y+(u+d+2*s.textMargin)-s.textMargin);break}if(s.anchor!==void 0&&s.textMargin!==void 0&&s.width!==void 0)switch(s.anchor){case"left":case"start":s.x=Math.round(s.x+s.textMargin),s.anchor="start",s.dominantBaseline="middle",s.alignmentBaseline="middle";break;case"middle":case"center":s.x=Math.round(s.x+s.width/2),s.anchor="middle",s.dominantBaseline="middle",s.alignmentBaseline="middle";break;case"right":case"end":s.x=Math.round(s.x+s.width-s.textMargin),s.anchor="end",s.dominantBaseline="middle",s.alignmentBaseline="middle";break}for(let[A,P]of p.entries()){s.textMargin!==void 0&&s.textMargin===0&&v!==void 0&&(T=A*v);const R=i.append("text");R.attr("x",s.x),R.attr("y",_()),s.anchor!==void 0&&R.attr("text-anchor",s.anchor).attr("dominant-baseline",s.dominantBaseline).attr("alignment-baseline",s.alignmentBaseline),s.fontFamily!==void 0&&R.style("font-family",s.fontFamily),b!==void 0&&R.style("font-size",b),s.fontWeight!==void 0&&R.style("font-weight",s.fontWeight),s.fill!==void 0&&R.attr("fill",s.fill),s.class!==void 0&&R.attr("class",s.class),s.dy!==void 0?R.attr("dy",s.dy):T!==0&&R.attr("dy",T);const F=P||hje;if(s.tspan){const j=R.append("tspan");j.attr("x",s.x),s.fill!==void 0&&j.attr("fill",s.fill),j.text(F)}else R.text(F);s.valign!==void 0&&s.textMargin!==void 0&&s.textMargin>0&&(d+=(R._groups||R)[0][0].getBBox().height,u=d),y.push(R)}return y},$Ge=function(i,s){function u(p,v,b,y,T){return p+","+v+" "+(p+b)+","+v+" "+(p+b)+","+(v+y-T)+" "+(p+b-T*1.2)+","+(v+y)+" "+p+","+(v+y)}const d=i.append("polygon");return d.attr("points",u(s.x,s.y,s.width,s.height,7)),d.attr("class","labelBox"),s.y=s.y+s.height/2,YD(i,s),d};let s5=-1;const zGe=(i,s,u,d)=>{i.select&&u.forEach(p=>{const v=s[p],b=i.select("#actor"+v.actorCnt);!d.mirrorActors&&v.stopy?b.attr("y2",v.stopy+v.height/2):d.mirrorActors&&b.attr("y2",v.stopy)})},Wrn=async function(i,s,u,d){const p=d?s.stopy:s.starty,v=s.x+s.width/2,b=p+5,y=i.append("g").lower();var T=y;d||(s5++,Object.keys(s.links||{}).length&&!u.forceMenus&&T.attr("onclick",Krn(`actor${s5}_popup`)).attr("cursor","pointer"),T.append("line").attr("id","actor"+s5).attr("x1",v).attr("y1",b).attr("x2",v).attr("y2",2e3).attr("class","actor-line").attr("class","200").attr("stroke-width","0.5px").attr("stroke","#999"),T=y.append("g"),s.actorCnt=s5,s.links!=null&&T.attr("id","root-"+s5));const _=qC();var A="actor";s.properties!=null&&s.properties.class?A=s.properties.class:_.fill="#eaeaea",d?A+=` ${jGe}`:A+=` ${RGe}`,_.x=s.x,_.y=p,_.width=s.width,_.height=s.height,_.class=A,_.rx=3,_.ry=3,_.name=s.name;const P=Eve(T,_);if(s.rectData=_,s.properties!=null&&s.properties.icon){const F=s.properties.icon.trim();F.charAt(0)==="@"?rUt(T,_.x+_.width-20,_.y+10,F.substr(1)):nUt(T,_.x+_.width-20,_.y+10,F)}await Tve(u,Dv(s.description))(s.description,T,_.x,_.y,_.width,_.height,{class:"actor"},u);let R=s.height;if(P.node){const F=P.node().getBBox();s.height=F.height,R=F.height}return R},Yrn=async function(i,s,u,d){const p=d?s.stopy:s.starty,v=s.x+s.width/2,b=p+80;i.lower(),d||(s5++,i.append("line").attr("id","actor"+s5).attr("x1",v).attr("y1",b).attr("x2",v).attr("y2",2e3).attr("class","actor-line").attr("class","200").attr("stroke-width","0.5px").attr("stroke","#999"),s.actorCnt=s5);const y=i.append("g");let T="actor-man";d?T+=` ${jGe}`:T+=` ${RGe}`,y.attr("class",T),y.attr("name",s.name);const _=qC();_.x=s.x,_.y=p,_.fill="#eaeaea",_.width=s.width,_.height=s.height,_.class="actor",_.rx=3,_.ry=3,y.append("line").attr("id","actor-man-torso"+s5).attr("x1",v).attr("y1",p+25).attr("x2",v).attr("y2",p+45),y.append("line").attr("id","actor-man-arms"+s5).attr("x1",v-ZC/2).attr("y1",p+33).attr("x2",v+ZC/2).attr("y2",p+33),y.append("line").attr("x1",v-ZC/2).attr("y1",p+60).attr("x2",v).attr("y2",p+45),y.append("line").attr("x1",v).attr("y1",p+45).attr("x2",v+ZC/2-2).attr("y2",p+60);const A=y.append("circle");A.attr("cx",s.x+s.width/2),A.attr("cy",p+10),A.attr("r",15),A.attr("width",s.width),A.attr("height",s.height);const P=y.node().getBBox();return s.height=P.height,await Tve(u,Dv(s.description))(s.description,y,_.x,_.y+35,_.width,_.height,{class:"actor"},u),s.height},Xrn=async function(i,s,u,d){switch(s.type){case"actor":return await Yrn(i,s,u,d);case"participant":return await Wrn(i,s,u,d)}},Qrn=async function(i,s,u){const p=i.append("g");qGe(p,s),s.name&&await Tve(u)(s.name,p,s.x,s.y+(s.textMaxHeight||0)/2,s.width,0,{class:"text"},u),p.lower()},Jrn=function(i){return i.append("g")},Zrn=function(i,s,u,d,p){const v=qC(),b=s.anchored;v.x=s.startx,v.y=s.starty,v.class="activation"+p%3,v.width=s.stopx-s.startx,v.height=u-s.starty,Eve(b,v)},ein=async function(i,s,u,d){const{boxMargin:p,boxTextMargin:v,labelBoxHeight:b,labelBoxWidth:y,messageFontFamily:T,messageFontSize:_,messageFontWeight:A}=d,P=i.append("g"),R=function(K,ee,ie,oe){return P.append("line").attr("x1",K).attr("y1",ee).attr("x2",ie).attr("y2",oe).attr("class","loopLine")};R(s.startx,s.starty,s.stopx,s.starty),R(s.stopx,s.starty,s.stopx,s.stopy),R(s.startx,s.stopy,s.stopx,s.stopy),R(s.startx,s.starty,s.startx,s.stopy),s.sections!==void 0&&s.sections.forEach(function(K){R(s.startx,K.y,s.stopx,K.y).style("stroke-dasharray","3, 3")});let F=zbe();F.text=u,F.x=s.startx,F.y=s.starty,F.fontFamily=T,F.fontSize=_,F.fontWeight=A,F.anchor="middle",F.valign="middle",F.tspan=!1,F.width=y||50,F.height=b||20,F.textMargin=v,F.class="labelText",$Ge(P,F),F=HGe(),F.text=s.title,F.x=s.startx+y/2+(s.stopx-s.startx)/2,F.y=s.starty+p+v,F.anchor="middle",F.valign="middle",F.textMargin=v,F.class="loopText",F.fontFamily=T,F.fontSize=_,F.fontWeight=A,F.wrap=!0;let j=Dv(F.text)?await pJ(P,F,s):YD(P,F);if(s.sectionTitles!==void 0){for(const[K,ee]of Object.entries(s.sectionTitles))if(ee.message){F.text=ee.message,F.x=s.startx+(s.stopx-s.startx)/2,F.y=s.sections[K].y+p+v,F.class="loopText",F.anchor="middle",F.valign="middle",F.tspan=!1,F.fontFamily=T,F.fontSize=_,F.fontWeight=A,F.wrap=s.wrap,Dv(F.text)?(s.starty=s.sections[K].y,await pJ(P,F,s)):YD(P,F);let ie=Math.round(j.map(oe=>(oe._groups||oe)[0][0].getBBox().height).reduce((oe,pe)=>oe+pe));s.sections[K].height+=ie-(p+v)}}return s.height=Math.round(s.stopy-s.starty),P},qGe=function(i,s){Tqe(i,s)},tin=function(i){i.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")},nin=function(i){i.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")},rin=function(i){i.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")},iin=function(i){i.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").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},sin=function(i){i.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")},ain=function(i){i.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)},oin=function(i){i.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")},HGe=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}},cin=function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},Tve=function(){function i(v,b,y,T,_,A,P){const R=b.append("text").attr("x",y+_/2).attr("y",T+A/2+5).style("text-anchor","middle").text(v);p(R,P)}function s(v,b,y,T,_,A,P,R){const{actorFontSize:F,actorFontFamily:j,actorFontWeight:K}=R,[ee,ie]=NC(F),oe=v.split(ci.lineBreakRegex);for(let pe=0;pei.height||0))+(this.loops.length===0?0:this.loops.map(i=>i.height||0).reduce((i,s)=>i+s))+(this.messages.length===0?0:this.messages.map(i=>i.height||0).reduce((i,s)=>i+s))+(this.notes.length===0?0:this.notes.map(i=>i.height||0).reduce((i,s)=>i+s))},clear:function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},addBox:function(i){this.boxes.push(i)},addActor:function(i){this.actors.push(i)},addLoop:function(i){this.loops.push(i)},addMessage:function(i){this.messages.push(i)},addNote:function(i){this.notes.push(i)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],boxes:[],loops:[],messages:[],notes:[]},init: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,UGe(qt())},updateVal:function(i,s,u,d){i[s]===void 0?i[s]=u:i[s]=d(u,i[s])},updateBounds:function(i,s,u,d){const p=this;let v=0;function b(y){return function(_){v++;const A=p.sequenceItems.length-v+1;p.updateVal(_,"starty",s-A*En.boxMargin,Math.min),p.updateVal(_,"stopy",d+A*En.boxMargin,Math.max),p.updateVal(ni.data,"startx",i-A*En.boxMargin,Math.min),p.updateVal(ni.data,"stopx",u+A*En.boxMargin,Math.max),y!=="activation"&&(p.updateVal(_,"startx",i-A*En.boxMargin,Math.min),p.updateVal(_,"stopx",u+A*En.boxMargin,Math.max),p.updateVal(ni.data,"starty",s-A*En.boxMargin,Math.min),p.updateVal(ni.data,"stopy",d+A*En.boxMargin,Math.max))}}this.sequenceItems.forEach(b()),this.activations.forEach(b("activation"))},insert:function(i,s,u,d){const p=ci.getMin(i,u),v=ci.getMax(i,u),b=ci.getMin(s,d),y=ci.getMax(s,d);this.updateVal(ni.data,"startx",p,Math.min),this.updateVal(ni.data,"starty",b,Math.min),this.updateVal(ni.data,"stopx",v,Math.max),this.updateVal(ni.data,"stopy",y,Math.max),this.updateBounds(p,b,v,y)},newActivation:function(i,s,u){const d=u[i.from.actor],p=bJ(i.from.actor).length||0,v=d.x+d.width/2+(p-1)*En.activationWidth/2;this.activations.push({startx:v,starty:this.verticalPos+2,stopx:v+En.activationWidth,stopy:void 0,actor:i.from.actor,anchored:Zf.anchorElement(s)})},endActivation:function(i){const s=this.activations.map(function(u){return u.actor}).lastIndexOf(i.from.actor);return this.activations.splice(s,1)[0]},createLoop:function(i={message:void 0,wrap:!1,width:void 0},s){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:i.message,wrap:i.wrap,width:i.width,height:0,fill:s}},newLoop:function(i={message:void 0,wrap:!1,width:void 0},s){this.sequenceItems.push(this.createLoop(i,s))},endLoop:function(){return this.sequenceItems.pop()},isLoopOverlap:function(){return this.sequenceItems.length?this.sequenceItems[this.sequenceItems.length-1].overlap:!1},addSectionToLoop:function(i){const s=this.sequenceItems.pop();s.sections=s.sections||[],s.sectionTitles=s.sectionTitles||[],s.sections.push({y:ni.getVerticalPos(),height:0}),s.sectionTitles.push(i),this.sequenceItems.push(s)},saveVerticalPos:function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},resetVerticalPos:function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},bumpVerticalPos:function(i){this.verticalPos=this.verticalPos+i,this.data.stopy=ci.getMax(this.data.stopy,this.verticalPos)},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},lin=async function(i,s){ni.bumpVerticalPos(En.boxMargin),s.height=En.boxMargin,s.starty=ni.getVerticalPos();const u=qC();u.x=s.startx,u.y=s.starty,u.width=s.width||En.width,u.class="note";const d=i.append("g"),p=Zf.drawRect(d,u),v=zbe();v.x=s.startx,v.y=s.starty,v.width=u.width,v.dy="1em",v.text=s.message,v.class="noteText",v.fontFamily=En.noteFontFamily,v.fontSize=En.noteFontSize,v.fontWeight=En.noteFontWeight,v.anchor=En.noteAlign,v.textMargin=En.noteMargin,v.valign="center";const b=Dv(v.text)?await pJ(d,v):YD(d,v),y=Math.round(b.map(T=>(T._groups||T)[0][0].getBBox().height).reduce((T,_)=>T+_));p.attr("height",y+2*En.noteMargin),s.height+=y+2*En.noteMargin,ni.bumpVerticalPos(y+2*En.noteMargin),s.stopy=s.starty+y+2*En.noteMargin,s.stopx=s.startx+u.width,ni.insert(s.startx,s.starty,s.stopx,s.stopy),ni.models.addNote(s)},eS=i=>({fontFamily:i.messageFontFamily,fontSize:i.messageFontSize,fontWeight:i.messageFontWeight}),XD=i=>({fontFamily:i.noteFontFamily,fontSize:i.noteFontSize,fontWeight:i.noteFontWeight}),Cve=i=>({fontFamily:i.actorFontFamily,fontSize:i.actorFontSize,fontWeight:i.actorFontWeight});async function hin(i,s){ni.bumpVerticalPos(10);const{startx:u,stopx:d,message:p}=s,v=ci.splitBreaks(p).length,b=Dv(p),y=b?await HF(p,qt()):Ao.calculateTextDimensions(p,eS(En));if(!b){const P=y.height/v;s.height+=P,ni.bumpVerticalPos(P)}let T,_=y.height-10;const A=y.width;if(u===d){T=ni.getVerticalPos()+_,En.rightAngles||(_+=En.boxMargin,T=ni.getVerticalPos()+_),_+=30;const P=ci.getMax(A/2,En.width/2);ni.insert(u-P,ni.getVerticalPos()-10+_,d+P,ni.getVerticalPos()+30+_)}else _+=En.boxMargin,T=ni.getVerticalPos()+_,ni.insert(u,T-10,d,T);return ni.bumpVerticalPos(_),s.height+=_,s.stopy=s.starty+s.height,ni.insert(s.fromBounds,s.starty,s.toBounds,s.stopy),T}const fin=async function(i,s,u,d){const{startx:p,stopx:v,starty:b,message:y,type:T,sequenceIndex:_,sequenceVisible:A}=s,P=Ao.calculateTextDimensions(y,eS(En)),R=zbe();R.x=p,R.y=b+10,R.width=v-p,R.class="messageText",R.dy="1em",R.text=y,R.fontFamily=En.messageFontFamily,R.fontSize=En.messageFontSize,R.fontWeight=En.messageFontWeight,R.anchor=En.messageAlign,R.valign="center",R.textMargin=En.wrapPadding,R.tspan=!1,Dv(R.text)?await pJ(i,R,{startx:p,stopx:v,starty:u}):YD(i,R);const F=P.width;let j;p===v?En.rightAngles?j=i.append("path").attr("d",`M ${p},${u} H ${p+ci.getMax(En.width/2,F/2)} V ${u+25} H ${p}`):j=i.append("path").attr("d","M "+p+","+u+" C "+(p+60)+","+(u-10)+" "+(p+60)+","+(u+30)+" "+p+","+(u+20)):(j=i.append("line"),j.attr("x1",p),j.attr("y1",u),j.attr("x2",v),j.attr("y2",u)),T===d.db.LINETYPE.DOTTED||T===d.db.LINETYPE.DOTTED_CROSS||T===d.db.LINETYPE.DOTTED_POINT||T===d.db.LINETYPE.DOTTED_OPEN?(j.style("stroke-dasharray","3, 3"),j.attr("class","messageLine1")):j.attr("class","messageLine0");let K="";En.arrowMarkerAbsolute&&(K=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,K=K.replace(/\(/g,"\\("),K=K.replace(/\)/g,"\\)")),j.attr("stroke-width",2),j.attr("stroke","none"),j.style("fill","none"),(T===d.db.LINETYPE.SOLID||T===d.db.LINETYPE.DOTTED)&&j.attr("marker-end","url("+K+"#arrowhead)"),(T===d.db.LINETYPE.SOLID_POINT||T===d.db.LINETYPE.DOTTED_POINT)&&j.attr("marker-end","url("+K+"#filled-head)"),(T===d.db.LINETYPE.SOLID_CROSS||T===d.db.LINETYPE.DOTTED_CROSS)&&j.attr("marker-end","url("+K+"#crosshead)"),(A||En.showSequenceNumbers)&&(j.attr("marker-start","url("+K+"#sequencenumber)"),i.append("text").attr("x",p).attr("y",u+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(_))},din=async function(i,s,u,d,p,v,b){let y=0,T=0,_,A=0;for(const P of d){const R=s[P],F=R.box;_&&_!=F&&(b||ni.models.addBox(_),T+=En.boxMargin+_.margin),F&&F!=_&&(b||(F.x=y+T,F.y=p),T+=F.margin),R.width=R.width||En.width,R.height=ci.getMax(R.height||En.height,En.height),R.margin=R.margin||En.actorMargin,A=ci.getMax(A,R.height),u[R.name]&&(T+=R.width/2),R.x=y+T,R.starty=ni.getVerticalPos(),ni.insert(R.x,p,R.x+R.width,R.height),y+=R.width+T,R.box&&(R.box.width=y+F.margin-R.box.x),T=R.margin,_=R.box,ni.models.addActor(R)}_&&!b&&ni.models.addBox(_),ni.bumpVerticalPos(A)},Sve=async function(i,s,u,d){if(d){let p=0;ni.bumpVerticalPos(En.boxMargin*2);for(const v of u){const b=s[v];b.stopy||(b.stopy=ni.getVerticalPos());const y=await Zf.drawActor(i,b,En,!0);p=ci.getMax(p,y)}ni.bumpVerticalPos(p+En.boxMargin)}else for(const p of u){const v=s[p];await Zf.drawActor(i,v,En,!1)}},VGe=function(i,s,u,d){let p=0,v=0;for(const b of u){const y=s[b],T=min(y),_=Zf.drawPopup(i,y,T,En,En.forceMenus,d);_.height>p&&(p=_.height),_.width+y.x>v&&(v=_.width+y.x)}return{maxHeight:p,maxWidth:v}},UGe=function(i){id(En,i),i.fontFamily&&(En.actorFontFamily=En.noteFontFamily=En.messageFontFamily=i.fontFamily),i.fontSize&&(En.actorFontSize=En.noteFontSize=En.messageFontSize=i.fontSize),i.fontWeight&&(En.actorFontWeight=En.noteFontWeight=En.messageFontWeight=i.fontWeight)},bJ=function(i){return ni.activations.filter(function(s){return s.actor===i})},GGe=function(i,s){const u=s[i],d=bJ(i),p=d.reduce(function(b,y){return ci.getMin(b,y.startx)},u.x+u.width/2-1),v=d.reduce(function(b,y){return ci.getMax(b,y.stopx)},u.x+u.width/2+1);return[p,v]};function a5(i,s,u,d,p){ni.bumpVerticalPos(u);let v=d;if(s.id&&s.message&&i[s.id]){const b=i[s.id].width,y=eS(En);s.message=Ao.wrapLabel(`[${s.message}]`,b-2*En.wrapPadding,y),s.width=b,s.wrap=!0;const T=Ao.calculateTextDimensions(s.message,y),_=ci.getMax(T.height,En.labelBoxHeight);v=d+_,Xe.debug(`${_} - ${s.message}`)}p(s),ni.bumpVerticalPos(v)}function gin(i,s,u,d,p,v,b){function y(_,A){_.x{Se.add(Ce.from),Se.add(Ce.to)}),j=j.filter(Ce=>Se.has(Ce))}await din(_,A,P,j,0,K,!1);const be=await xin(K,A,pe,d);Zf.insertArrowHead(_),Zf.insertArrowCrossHead(_),Zf.insertArrowFilledHead(_),Zf.insertSequenceNumber(_);function ae(Se,Ce){const ke=ni.endActivation(Se);ke.starty+18>Ce&&(ke.starty=Ce-6,Ce+=12),Zf.drawActivation(_,ke,Ce,En,bJ(Se.from.actor).length),ni.insert(ke.startx,Ce-10,ke.stopx,Ce)}let ne=1,se=1;const de=[],X=[];let ge=0;for(const Se of K){let Ce,ke,Ke;switch(Se.type){case d.db.LINETYPE.NOTE:ni.resetVerticalPos(),ke=Se.noteModel,await lin(_,ke);break;case d.db.LINETYPE.ACTIVE_START:ni.newActivation(Se,_,A);break;case d.db.LINETYPE.ACTIVE_END:ae(Se,ni.getVerticalPos());break;case d.db.LINETYPE.LOOP_START:a5(be,Se,En.boxMargin,En.boxMargin+En.boxTextMargin,Ft=>ni.newLoop(Ft));break;case d.db.LINETYPE.LOOP_END:Ce=ni.endLoop(),await Zf.drawLoop(_,Ce,"loop",En),ni.bumpVerticalPos(Ce.stopy-ni.getVerticalPos()),ni.models.addLoop(Ce);break;case d.db.LINETYPE.RECT_START:a5(be,Se,En.boxMargin,En.boxMargin,Ft=>ni.newLoop(void 0,Ft.message));break;case d.db.LINETYPE.RECT_END:Ce=ni.endLoop(),X.push(Ce),ni.models.addLoop(Ce),ni.bumpVerticalPos(Ce.stopy-ni.getVerticalPos());break;case d.db.LINETYPE.OPT_START:a5(be,Se,En.boxMargin,En.boxMargin+En.boxTextMargin,Ft=>ni.newLoop(Ft));break;case d.db.LINETYPE.OPT_END:Ce=ni.endLoop(),await Zf.drawLoop(_,Ce,"opt",En),ni.bumpVerticalPos(Ce.stopy-ni.getVerticalPos()),ni.models.addLoop(Ce);break;case d.db.LINETYPE.ALT_START:a5(be,Se,En.boxMargin,En.boxMargin+En.boxTextMargin,Ft=>ni.newLoop(Ft));break;case d.db.LINETYPE.ALT_ELSE:a5(be,Se,En.boxMargin+En.boxTextMargin,En.boxMargin,Ft=>ni.addSectionToLoop(Ft));break;case d.db.LINETYPE.ALT_END:Ce=ni.endLoop(),await Zf.drawLoop(_,Ce,"alt",En),ni.bumpVerticalPos(Ce.stopy-ni.getVerticalPos()),ni.models.addLoop(Ce);break;case d.db.LINETYPE.PAR_START:case d.db.LINETYPE.PAR_OVER_START:a5(be,Se,En.boxMargin,En.boxMargin+En.boxTextMargin,Ft=>ni.newLoop(Ft)),ni.saveVerticalPos();break;case d.db.LINETYPE.PAR_AND:a5(be,Se,En.boxMargin+En.boxTextMargin,En.boxMargin,Ft=>ni.addSectionToLoop(Ft));break;case d.db.LINETYPE.PAR_END:Ce=ni.endLoop(),await Zf.drawLoop(_,Ce,"par",En),ni.bumpVerticalPos(Ce.stopy-ni.getVerticalPos()),ni.models.addLoop(Ce);break;case d.db.LINETYPE.AUTONUMBER:ne=Se.message.start||ne,se=Se.message.step||se,Se.message.visible?d.db.enableSequenceNumbers():d.db.disableSequenceNumbers();break;case d.db.LINETYPE.CRITICAL_START:a5(be,Se,En.boxMargin,En.boxMargin+En.boxTextMargin,Ft=>ni.newLoop(Ft));break;case d.db.LINETYPE.CRITICAL_OPTION:a5(be,Se,En.boxMargin+En.boxTextMargin,En.boxMargin,Ft=>ni.addSectionToLoop(Ft));break;case d.db.LINETYPE.CRITICAL_END:Ce=ni.endLoop(),await Zf.drawLoop(_,Ce,"critical",En),ni.bumpVerticalPos(Ce.stopy-ni.getVerticalPos()),ni.models.addLoop(Ce);break;case d.db.LINETYPE.BREAK_START:a5(be,Se,En.boxMargin,En.boxMargin+En.boxTextMargin,Ft=>ni.newLoop(Ft));break;case d.db.LINETYPE.BREAK_END:Ce=ni.endLoop(),await Zf.drawLoop(_,Ce,"break",En),ni.bumpVerticalPos(Ce.stopy-ni.getVerticalPos()),ni.models.addLoop(Ce);break;default:try{Ke=Se.msgModel,Ke.starty=ni.getVerticalPos(),Ke.sequenceIndex=ne,Ke.sequenceVisible=d.db.showSequenceNumbers();const Ft=await hin(_,Ke);gin(Se,Ke,Ft,ge,A,P,R),de.push({messageModel:Ke,lineStartY:Ft}),ni.models.addMessage(Ke)}catch(Ft){Xe.error("error while drawing message",Ft)}}[d.db.LINETYPE.SOLID_OPEN,d.db.LINETYPE.DOTTED_OPEN,d.db.LINETYPE.SOLID,d.db.LINETYPE.DOTTED,d.db.LINETYPE.SOLID_CROSS,d.db.LINETYPE.DOTTED_CROSS,d.db.LINETYPE.SOLID_POINT,d.db.LINETYPE.DOTTED_POINT].includes(Se.type)&&(ne=ne+se),ge++}Xe.debug("createdActors",P),Xe.debug("destroyedActors",R),await Sve(_,A,j,!1);for(const Se of de)await fin(_,Se.messageModel,Se.lineStartY,d);En.mirrorActors&&await Sve(_,A,j,!0),X.forEach(Se=>Zf.drawBackgroundRect(_,Se)),zGe(_,A,j,En);for(const Se of ni.models.boxes)Se.height=ni.getVerticalPos()-Se.y,ni.insert(Se.x,Se.y,Se.x+Se.width,Se.height),Se.startx=Se.x,Se.starty=Se.y,Se.stopx=Se.startx+Se.width,Se.stopy=Se.starty+Se.height,Se.stroke="rgb(0,0,0, 0.5)",await Zf.drawBox(_,Se,En);ie&&ni.bumpVerticalPos(En.boxMargin);const W=VGe(_,A,j,T),{bounds:xe}=ni.getBounds();let U=xe.stopy-xe.starty;U{const b=eS(En);let y=v.actorKeys.reduce((A,P)=>A+=i[P].width+(i[P].margin||0),0);y-=2*En.boxTextMargin,v.wrap&&(v.name=Ao.wrapLabel(v.name,y-2*En.wrapPadding,b));const T=Ao.calculateTextDimensions(v.name,b);p=ci.getMax(T.height,p);const _=ci.getMax(y,T.width+2*En.wrapPadding);if(v.margin=En.boxTextMargin,y<_){const A=(_-y)/2;v.margin+=A}}),u.forEach(v=>v.textMaxHeight=p),ci.getMax(d,En.height)}const win=async function(i,s,u){const d=s[i.from].x,p=s[i.to].x,v=i.wrap&&i.message;let b=Dv(i.message)?await HF(i.message,qt()):Ao.calculateTextDimensions(v?Ao.wrapLabel(i.message,En.width,XD(En)):i.message,XD(En));const y={width:v?En.width:ci.getMax(En.width,b.width+2*En.noteMargin),height:0,startx:s[i.from].x,stopx:0,starty:0,stopy:0,message:i.message};return i.placement===u.db.PLACEMENT.RIGHTOF?(y.width=v?ci.getMax(En.width,b.width):ci.getMax(s[i.from].width/2+s[i.to].width/2,b.width+2*En.noteMargin),y.startx=d+(s[i.from].width+En.actorMargin)/2):i.placement===u.db.PLACEMENT.LEFTOF?(y.width=v?ci.getMax(En.width,b.width+2*En.noteMargin):ci.getMax(s[i.from].width/2+s[i.to].width/2,b.width+2*En.noteMargin),y.startx=d-y.width+(s[i.from].width-En.actorMargin)/2):i.to===i.from?(b=Ao.calculateTextDimensions(v?Ao.wrapLabel(i.message,ci.getMax(En.width,s[i.from].width),XD(En)):i.message,XD(En)),y.width=v?ci.getMax(En.width,s[i.from].width):ci.getMax(s[i.from].width,En.width,b.width+2*En.noteMargin),y.startx=d+(s[i.from].width-y.width)/2):(y.width=Math.abs(d+s[i.from].width/2-(p+s[i.to].width/2))+En.actorMargin,y.startx=d2,P=K=>y?-K:K;i.from===i.to?_=T:(i.activate&&!A&&(_+=P(En.activationWidth/2-1)),[u.db.LINETYPE.SOLID_OPEN,u.db.LINETYPE.DOTTED_OPEN].includes(i.type)||(_+=P(3)));const R=[d,p,v,b],F=Math.abs(T-_);i.wrap&&i.message&&(i.message=Ao.wrapLabel(i.message,ci.getMax(F+2*En.wrapPadding,En.width),eS(En)));const j=Ao.calculateTextDimensions(i.message,eS(En));return{width:ci.getMax(i.wrap?0:j.width+2*En.wrapPadding,F+2*En.wrapPadding,En.width),height:0,startx:T,stopx:_,starty:0,stopy:0,message:i.message,type:i.type,wrap:i.wrap,fromBounds:Math.min.apply(null,R),toBounds:Math.max.apply(null,R)}},xin=async function(i,s,u,d){const p={},v=[];let b,y,T;for(const _ of i){switch(_.id=Ao.random({length:10}),_.type){case d.db.LINETYPE.LOOP_START:case d.db.LINETYPE.ALT_START:case d.db.LINETYPE.OPT_START:case d.db.LINETYPE.PAR_START:case d.db.LINETYPE.PAR_OVER_START:case d.db.LINETYPE.CRITICAL_START:case d.db.LINETYPE.BREAK_START:v.push({id:_.id,msg:_.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case d.db.LINETYPE.ALT_ELSE:case d.db.LINETYPE.PAR_AND:case d.db.LINETYPE.CRITICAL_OPTION:_.message&&(b=v.pop(),p[b.id]=b,p[_.id]=b,v.push(b));break;case d.db.LINETYPE.LOOP_END:case d.db.LINETYPE.ALT_END:case d.db.LINETYPE.OPT_END:case d.db.LINETYPE.PAR_END:case d.db.LINETYPE.CRITICAL_END:case d.db.LINETYPE.BREAK_END:b=v.pop(),p[b.id]=b;break;case d.db.LINETYPE.ACTIVE_START:{const P=s[_.from?_.from.actor:_.to.actor],R=bJ(_.from?_.from.actor:_.to.actor).length,F=P.x+P.width/2+(R-1)*En.activationWidth/2,j={startx:F,stopx:F+En.activationWidth,actor:_.from.actor,enabled:!0};ni.activations.push(j)}break;case d.db.LINETYPE.ACTIVE_END:{const P=ni.activations.map(R=>R.actor).lastIndexOf(_.from.actor);delete ni.activations.splice(P,1)[0]}break}_.placement!==void 0?(y=await win(_,s,d),_.noteModel=y,v.forEach(P=>{b=P,b.from=ci.getMin(b.from,y.startx),b.to=ci.getMax(b.to,y.startx+y.width),b.width=ci.getMax(b.width,Math.abs(b.from-b.to))-En.labelBoxWidth})):(T=yin(_,s,d),_.msgModel=T,T.startx&&T.stopx&&v.length>0&&v.forEach(P=>{if(b=P,T.startx===T.stopx){const R=s[_.from],F=s[_.to];b.from=ci.getMin(R.x-T.width/2,R.x-R.width/2,b.from),b.to=ci.getMax(F.x+T.width/2,F.x+R.width/2,b.to),b.width=ci.getMax(b.width,Math.abs(b.to-b.from))-En.labelBoxWidth}else b.from=ci.getMin(T.startx,b.from),b.to=ci.getMax(T.stopx,b.to),b.width=ci.getMax(b.width,T.width)-En.labelBoxWidth}))}return ni.activations=[],Xe.debug("Loop type widths:",p),p},kin=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:yrn,db:FGe,renderer:{bounds:ni,drawActors:Sve,drawActorsPopup:VGe,setConf:UGe,draw:pin},styles:Urn,init:({wrap:i})=>{FGe.setWrap(i)}}},Symbol.toStringTag,{value:"Module"}));var _ve=function(){var i=function(ao,Tr,Fn,qn){for(Fn=Fn||{},qn=ao.length;qn--;Fn[ao[qn]]=Tr);return Fn},s=[1,17],u=[1,18],d=[1,19],p=[1,39],v=[1,40],b=[1,25],y=[1,23],T=[1,24],_=[1,31],A=[1,32],P=[1,33],R=[1,34],F=[1,35],j=[1,36],K=[1,26],ee=[1,27],ie=[1,28],oe=[1,29],pe=[1,43],be=[1,30],ae=[1,42],ne=[1,44],se=[1,41],de=[1,45],X=[1,9],ge=[1,8,9],W=[1,56],xe=[1,57],U=[1,58],Fe=[1,59],Pe=[1,60],je=[1,61],Ie=[1,62],Se=[1,8,9,39],Ce=[1,74],ke=[1,8,9,12,13,21,37,39,42,59,60,61,62,63,64,65,70,72],Ke=[1,8,9,12,13,19,21,37,39,42,46,59,60,61,62,63,64,65,70,72,74,80,95,97,98],Ft=[13,74,80,95,97,98],Ne=[13,64,65,74,80,95,97,98],gn=[13,59,60,61,62,63,74,80,95,97,98],_t=[1,93],Et=[1,110],Gt=[1,108],ln=[1,102],xt=[1,103],Pt=[1,104],Qe=[1,105],Dt=[1,106],kt=[1,107],On=[1,109],ht=[1,8,9,37,39,42],zr=[1,8,9,21],yt=[1,8,9,78],ji=[1,8,9,21,73,74,78,80,81,82,83,84,85],xi={trace:function(){},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,className:17,classLiteralName:18,GENERICTYPE:19,relationStatement:20,LABEL:21,namespaceStatement:22,classStatement:23,memberStatement:24,annotationStatement:25,clickStatement:26,styleStatement:27,cssClassStatement:28,noteStatement:29,direction:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,namespaceIdentifier:36,STRUCT_START:37,classStatements:38,STRUCT_STOP:39,NAMESPACE:40,classIdentifier:41,STYLE_SEPARATOR:42,members:43,CLASS:44,ANNOTATION_START:45,ANNOTATION_END:46,MEMBER:47,SEPARATOR:48,relation:49,NOTE_FOR:50,noteText:51,NOTE:52,direction_tb:53,direction_bt:54,direction_rl:55,direction_lr:56,relationType:57,lineType:58,AGGREGATION:59,EXTENSION:60,COMPOSITION:61,DEPENDENCY:62,LOLLIPOP:63,LINE:64,DOTTED_LINE:65,CALLBACK:66,LINK:67,LINK_TARGET:68,CLICK:69,CALLBACK_NAME:70,CALLBACK_ARGS:71,HREF:72,STYLE:73,ALPHA:74,stylesOpt:75,CSSCLASS:76,style:77,COMMA:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,commentToken:86,textToken:87,graphCodeTokens:88,textNoTagsToken:89,TAGSTART:90,TAGEND:91,"==":92,"--":93,DEFAULT:94,MINUS:95,keywords:96,UNICODE_TEXT:97,BQUOTE_STR:98,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",19:"GENERICTYPE",21:"LABEL",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",37:"STRUCT_START",39:"STRUCT_STOP",40:"NAMESPACE",42:"STYLE_SEPARATOR",44:"CLASS",45:"ANNOTATION_START",46:"ANNOTATION_END",47:"MEMBER",48:"SEPARATOR",50:"NOTE_FOR",52:"NOTE",53:"direction_tb",54:"direction_bt",55:"direction_rl",56:"direction_lr",59:"AGGREGATION",60:"EXTENSION",61:"COMPOSITION",62:"DEPENDENCY",63:"LOLLIPOP",64:"LINE",65:"DOTTED_LINE",66:"CALLBACK",67:"LINK",68:"LINK_TARGET",69:"CLICK",70:"CALLBACK_NAME",71:"CALLBACK_ARGS",72:"HREF",73:"STYLE",74:"ALPHA",76:"CSSCLASS",78:"COMMA",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",88:"graphCodeTokens",90:"TAGSTART",91:"TAGEND",92:"==",93:"--",94:"DEFAULT",95:"MINUS",96:"keywords",97:"UNICODE_TEXT",98:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,2],[17,1],[17,1],[17,2],[17,2],[17,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[22,4],[22,5],[36,2],[38,1],[38,2],[38,3],[23,1],[23,3],[23,4],[23,6],[41,2],[41,3],[25,4],[43,1],[43,2],[24,1],[24,2],[24,1],[24,1],[20,3],[20,4],[20,4],[20,5],[29,3],[29,2],[30,1],[30,1],[30,1],[30,1],[49,3],[49,2],[49,2],[49,1],[57,1],[57,1],[57,1],[57,1],[57,1],[58,1],[58,1],[26,3],[26,4],[26,3],[26,4],[26,4],[26,5],[26,3],[26,4],[26,4],[26,5],[26,4],[26,5],[26,5],[26,6],[27,3],[28,3],[75,1],[75,3],[77,1],[77,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[86,1],[86,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[89,1],[89,1],[89,1],[89,1],[16,1],[16,1],[16,1],[16,1],[18,1],[51,1]],performAction:function(Tr,Fn,qn,Un,At,wt,on){var fn=wt.length-1;switch(At){case 8:this.$=wt[fn-1];break;case 9:case 11:case 12:this.$=wt[fn];break;case 10:case 13:this.$=wt[fn-1]+wt[fn];break;case 14:case 15:this.$=wt[fn-1]+"~"+wt[fn]+"~";break;case 16:Un.addRelation(wt[fn]);break;case 17:wt[fn-1].title=Un.cleanupLabel(wt[fn]),Un.addRelation(wt[fn-1]);break;case 27:this.$=wt[fn].trim(),Un.setAccTitle(this.$);break;case 28:case 29:this.$=wt[fn].trim(),Un.setAccDescription(this.$);break;case 30:Un.addClassesToNamespace(wt[fn-3],wt[fn-1]);break;case 31:Un.addClassesToNamespace(wt[fn-4],wt[fn-1]);break;case 32:this.$=wt[fn],Un.addNamespace(wt[fn]);break;case 33:this.$=[wt[fn]];break;case 34:this.$=[wt[fn-1]];break;case 35:wt[fn].unshift(wt[fn-2]),this.$=wt[fn];break;case 37:Un.setCssClass(wt[fn-2],wt[fn]);break;case 38:Un.addMembers(wt[fn-3],wt[fn-1]);break;case 39:Un.setCssClass(wt[fn-5],wt[fn-3]),Un.addMembers(wt[fn-5],wt[fn-1]);break;case 40:this.$=wt[fn],Un.addClass(wt[fn]);break;case 41:this.$=wt[fn-1],Un.addClass(wt[fn-1]),Un.setClassLabel(wt[fn-1],wt[fn]);break;case 42:Un.addAnnotation(wt[fn],wt[fn-2]);break;case 43:this.$=[wt[fn]];break;case 44:wt[fn].push(wt[fn-1]),this.$=wt[fn];break;case 45:break;case 46:Un.addMember(wt[fn-1],Un.cleanupLabel(wt[fn]));break;case 47:break;case 48:break;case 49:this.$={id1:wt[fn-2],id2:wt[fn],relation:wt[fn-1],relationTitle1:"none",relationTitle2:"none"};break;case 50:this.$={id1:wt[fn-3],id2:wt[fn],relation:wt[fn-1],relationTitle1:wt[fn-2],relationTitle2:"none"};break;case 51:this.$={id1:wt[fn-3],id2:wt[fn],relation:wt[fn-2],relationTitle1:"none",relationTitle2:wt[fn-1]};break;case 52:this.$={id1:wt[fn-4],id2:wt[fn],relation:wt[fn-2],relationTitle1:wt[fn-3],relationTitle2:wt[fn-1]};break;case 53:Un.addNote(wt[fn],wt[fn-1]);break;case 54:Un.addNote(wt[fn]);break;case 55:Un.setDirection("TB");break;case 56:Un.setDirection("BT");break;case 57:Un.setDirection("RL");break;case 58:Un.setDirection("LR");break;case 59:this.$={type1:wt[fn-2],type2:wt[fn],lineType:wt[fn-1]};break;case 60:this.$={type1:"none",type2:wt[fn],lineType:wt[fn-1]};break;case 61:this.$={type1:wt[fn-1],type2:"none",lineType:wt[fn]};break;case 62:this.$={type1:"none",type2:"none",lineType:wt[fn]};break;case 63:this.$=Un.relationType.AGGREGATION;break;case 64:this.$=Un.relationType.EXTENSION;break;case 65:this.$=Un.relationType.COMPOSITION;break;case 66:this.$=Un.relationType.DEPENDENCY;break;case 67:this.$=Un.relationType.LOLLIPOP;break;case 68:this.$=Un.lineType.LINE;break;case 69:this.$=Un.lineType.DOTTED_LINE;break;case 70:case 76:this.$=wt[fn-2],Un.setClickEvent(wt[fn-1],wt[fn]);break;case 71:case 77:this.$=wt[fn-3],Un.setClickEvent(wt[fn-2],wt[fn-1]),Un.setTooltip(wt[fn-2],wt[fn]);break;case 72:this.$=wt[fn-2],Un.setLink(wt[fn-1],wt[fn]);break;case 73:this.$=wt[fn-3],Un.setLink(wt[fn-2],wt[fn-1],wt[fn]);break;case 74:this.$=wt[fn-3],Un.setLink(wt[fn-2],wt[fn-1]),Un.setTooltip(wt[fn-2],wt[fn]);break;case 75:this.$=wt[fn-4],Un.setLink(wt[fn-3],wt[fn-2],wt[fn]),Un.setTooltip(wt[fn-3],wt[fn-1]);break;case 78:this.$=wt[fn-3],Un.setClickEvent(wt[fn-2],wt[fn-1],wt[fn]);break;case 79:this.$=wt[fn-4],Un.setClickEvent(wt[fn-3],wt[fn-2],wt[fn-1]),Un.setTooltip(wt[fn-3],wt[fn]);break;case 80:this.$=wt[fn-3],Un.setLink(wt[fn-2],wt[fn]);break;case 81:this.$=wt[fn-4],Un.setLink(wt[fn-3],wt[fn-1],wt[fn]);break;case 82:this.$=wt[fn-4],Un.setLink(wt[fn-3],wt[fn-1]),Un.setTooltip(wt[fn-3],wt[fn]);break;case 83:this.$=wt[fn-5],Un.setLink(wt[fn-4],wt[fn-2],wt[fn]),Un.setTooltip(wt[fn-4],wt[fn-1]);break;case 84:this.$=wt[fn-2],Un.setCssStyle(wt[fn-1],wt[fn]);break;case 85:Un.setCssClass(wt[fn-1],wt[fn]);break;case 86:this.$=[wt[fn]];break;case 87:wt[fn-2].push(wt[fn]),this.$=wt[fn-2];break;case 89:this.$=wt[fn-1]+wt[fn];break}},table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:s,33:u,35:d,36:21,40:p,41:22,44:v,45:b,47:y,48:T,50:_,52:A,53:P,54:R,55:F,56:j,66:K,67:ee,69:ie,73:oe,74:pe,76:be,80:ae,95:ne,97:se,98:de},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},i(X,[2,5],{8:[1,46]}),{8:[1,47]},i(ge,[2,16],{21:[1,48]}),i(ge,[2,18]),i(ge,[2,19]),i(ge,[2,20]),i(ge,[2,21]),i(ge,[2,22]),i(ge,[2,23]),i(ge,[2,24]),i(ge,[2,25]),i(ge,[2,26]),{32:[1,49]},{34:[1,50]},i(ge,[2,29]),i(ge,[2,45],{49:51,57:54,58:55,13:[1,52],21:[1,53],59:W,60:xe,61:U,62:Fe,63:Pe,64:je,65:Ie}),{37:[1,63]},i(Se,[2,36],{37:[1,65],42:[1,64]}),i(ge,[2,47]),i(ge,[2,48]),{16:66,74:pe,80:ae,95:ne,97:se},{16:37,17:67,18:38,74:pe,80:ae,95:ne,97:se,98:de},{16:37,17:68,18:38,74:pe,80:ae,95:ne,97:se,98:de},{16:37,17:69,18:38,74:pe,80:ae,95:ne,97:se,98:de},{74:[1,70]},{13:[1,71]},{16:37,17:72,18:38,74:pe,80:ae,95:ne,97:se,98:de},{13:Ce,51:73},i(ge,[2,55]),i(ge,[2,56]),i(ge,[2,57]),i(ge,[2,58]),i(ke,[2,11],{16:37,18:38,17:75,19:[1,76],74:pe,80:ae,95:ne,97:se,98:de}),i(ke,[2,12],{19:[1,77]}),{15:78,16:79,74:pe,80:ae,95:ne,97:se},{16:37,17:80,18:38,74:pe,80:ae,95:ne,97:se,98:de},i(Ke,[2,112]),i(Ke,[2,113]),i(Ke,[2,114]),i(Ke,[2,115]),i([1,8,9,12,13,19,21,37,39,42,59,60,61,62,63,64,65,70,72],[2,116]),i(X,[2,6],{10:5,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,17:20,36:21,41:22,16:37,18:38,5:81,31:s,33:u,35:d,40:p,44:v,45:b,47:y,48:T,50:_,52:A,53:P,54:R,55:F,56:j,66:K,67:ee,69:ie,73:oe,74:pe,76:be,80:ae,95:ne,97:se,98:de}),{5:82,10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:s,33:u,35:d,36:21,40:p,41:22,44:v,45:b,47:y,48:T,50:_,52:A,53:P,54:R,55:F,56:j,66:K,67:ee,69:ie,73:oe,74:pe,76:be,80:ae,95:ne,97:se,98:de},i(ge,[2,17]),i(ge,[2,27]),i(ge,[2,28]),{13:[1,84],16:37,17:83,18:38,74:pe,80:ae,95:ne,97:se,98:de},{49:85,57:54,58:55,59:W,60:xe,61:U,62:Fe,63:Pe,64:je,65:Ie},i(ge,[2,46]),{58:86,64:je,65:Ie},i(Ft,[2,62],{57:87,59:W,60:xe,61:U,62:Fe,63:Pe}),i(Ne,[2,63]),i(Ne,[2,64]),i(Ne,[2,65]),i(Ne,[2,66]),i(Ne,[2,67]),i(gn,[2,68]),i(gn,[2,69]),{8:[1,89],23:90,38:88,41:22,44:v},{16:91,74:pe,80:ae,95:ne,97:se},{43:92,47:_t},{46:[1,94]},{13:[1,95]},{13:[1,96]},{70:[1,97],72:[1,98]},{21:Et,73:Gt,74:ln,75:99,77:100,79:101,80:xt,81:Pt,82:Qe,83:Dt,84:kt,85:On},{74:[1,111]},{13:Ce,51:112},i(ge,[2,54]),i(ge,[2,117]),i(ke,[2,13]),i(ke,[2,14]),i(ke,[2,15]),{37:[2,32]},{15:113,16:79,37:[2,9],74:pe,80:ae,95:ne,97:se},i(ht,[2,40],{11:114,12:[1,115]}),i(X,[2,7]),{9:[1,116]},i(zr,[2,49]),{16:37,17:117,18:38,74:pe,80:ae,95:ne,97:se,98:de},{13:[1,119],16:37,17:118,18:38,74:pe,80:ae,95:ne,97:se,98:de},i(Ft,[2,61],{57:120,59:W,60:xe,61:U,62:Fe,63:Pe}),i(Ft,[2,60]),{39:[1,121]},{23:90,38:122,41:22,44:v},{8:[1,123],39:[2,33]},i(Se,[2,37],{37:[1,124]}),{39:[1,125]},{39:[2,43],43:126,47:_t},{16:37,17:127,18:38,74:pe,80:ae,95:ne,97:se,98:de},i(ge,[2,70],{13:[1,128]}),i(ge,[2,72],{13:[1,130],68:[1,129]}),i(ge,[2,76],{13:[1,131],71:[1,132]}),{13:[1,133]},i(ge,[2,84],{78:[1,134]}),i(yt,[2,86],{79:135,21:Et,73:Gt,74:ln,80:xt,81:Pt,82:Qe,83:Dt,84:kt,85:On}),i(ji,[2,88]),i(ji,[2,90]),i(ji,[2,91]),i(ji,[2,92]),i(ji,[2,93]),i(ji,[2,94]),i(ji,[2,95]),i(ji,[2,96]),i(ji,[2,97]),i(ji,[2,98]),i(ge,[2,85]),i(ge,[2,53]),{37:[2,10]},i(ht,[2,41]),{13:[1,136]},{1:[2,4]},i(zr,[2,51]),i(zr,[2,50]),{16:37,17:137,18:38,74:pe,80:ae,95:ne,97:se,98:de},i(Ft,[2,59]),i(ge,[2,30]),{39:[1,138]},{23:90,38:139,39:[2,34],41:22,44:v},{43:140,47:_t},i(Se,[2,38]),{39:[2,44]},i(ge,[2,42]),i(ge,[2,71]),i(ge,[2,73]),i(ge,[2,74],{68:[1,141]}),i(ge,[2,77]),i(ge,[2,78],{13:[1,142]}),i(ge,[2,80],{13:[1,144],68:[1,143]}),{21:Et,73:Gt,74:ln,77:145,79:101,80:xt,81:Pt,82:Qe,83:Dt,84:kt,85:On},i(ji,[2,89]),{14:[1,146]},i(zr,[2,52]),i(ge,[2,31]),{39:[2,35]},{39:[1,147]},i(ge,[2,75]),i(ge,[2,79]),i(ge,[2,81]),i(ge,[2,82],{68:[1,148]}),i(yt,[2,87],{79:135,21:Et,73:Gt,74:ln,80:xt,81:Pt,82:Qe,83:Dt,84:kt,85:On}),i(ht,[2,8]),i(Se,[2,39]),i(ge,[2,83])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],78:[2,32],113:[2,10],116:[2,4],126:[2,44],139:[2,35]},parseError:function(Tr,Fn){if(Fn.recoverable)this.trace(Tr);else{var qn=new Error(Tr);throw qn.hash=Fn,qn}},parse:function(Tr){var Fn=this,qn=[0],Un=[],At=[null],wt=[],on=this.table,fn="",An=0,oo=0,jo=2,$o=1,Pa=wt.slice.call(arguments,1),wo=Object.create(this.lexer),_s={yy:{}};for(var tl in this.yy)Object.prototype.hasOwnProperty.call(this.yy,tl)&&(_s.yy[tl]=this.yy[tl]);wo.setInput(Tr,_s.yy),_s.yy.lexer=wo,_s.yy.parser=this,typeof wo.yylloc>"u"&&(wo.yylloc={});var da=wo.yylloc;wt.push(da);var j0=wo.options&&wo.options.ranges;typeof _s.yy.parseError=="function"?this.parseError=_s.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function pm(){var ga;return ga=Un.pop()||wo.lex()||$o,typeof ga!="number"&&(ga instanceof Array&&(Un=ga,ga=Un.pop()),ga=Fn.symbols_[ga]||ga),ga}for(var Ml,Xc,Bc,ja,Ou={},Sa,Po,Fc,xa;;){if(Xc=qn[qn.length-1],this.defaultActions[Xc]?Bc=this.defaultActions[Xc]:((Ml===null||typeof Ml>"u")&&(Ml=pm()),Bc=on[Xc]&&on[Xc][Ml]),typeof Bc>"u"||!Bc.length||!Bc[0]){var Ba="";xa=[];for(Sa in on[Xc])this.terminals_[Sa]&&Sa>jo&&xa.push("'"+this.terminals_[Sa]+"'");wo.showPosition?Ba="Parse error on line "+(An+1)+`: +`+wo.showPosition()+` +Expecting `+xa.join(", ")+", got '"+(this.terminals_[Ml]||Ml)+"'":Ba="Parse error on line "+(An+1)+": Unexpected "+(Ml==$o?"end of input":"'"+(this.terminals_[Ml]||Ml)+"'"),this.parseError(Ba,{text:wo.match,token:this.terminals_[Ml]||Ml,line:wo.yylineno,loc:da,expected:xa})}if(Bc[0]instanceof Array&&Bc.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Xc+", token: "+Ml);switch(Bc[0]){case 1:qn.push(Ml),At.push(wo.yytext),wt.push(wo.yylloc),qn.push(Bc[1]),Ml=null,oo=wo.yyleng,fn=wo.yytext,An=wo.yylineno,da=wo.yylloc;break;case 2:if(Po=this.productions_[Bc[1]][1],Ou.$=At[At.length-Po],Ou._$={first_line:wt[wt.length-(Po||1)].first_line,last_line:wt[wt.length-1].last_line,first_column:wt[wt.length-(Po||1)].first_column,last_column:wt[wt.length-1].last_column},j0&&(Ou._$.range=[wt[wt.length-(Po||1)].range[0],wt[wt.length-1].range[1]]),ja=this.performAction.apply(Ou,[fn,oo,An,_s.yy,Bc[1],At,wt].concat(Pa)),typeof ja<"u")return ja;Po&&(qn=qn.slice(0,-1*Po*2),At=At.slice(0,-1*Po),wt=wt.slice(0,-1*Po)),qn.push(this.productions_[Bc[1]][0]),At.push(Ou.$),wt.push(Ou._$),Fc=on[qn[qn.length-2]][qn[qn.length-1]],qn.push(Fc);break;case 3:return!0}}return!0}},Ma=function(){var ao={EOF:1,parseError:function(Fn,qn){if(this.yy.parser)this.yy.parser.parseError(Fn,qn);else throw new Error(Fn)},setInput:function(Tr,Fn){return this.yy=Fn||this.yy||{},this._input=Tr,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},input:function(){var Tr=this._input[0];this.yytext+=Tr,this.yyleng++,this.offset++,this.match+=Tr,this.matched+=Tr;var Fn=Tr.match(/(?:\r\n?|\n).*/g);return Fn?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Tr},unput:function(Tr){var Fn=Tr.length,qn=Tr.split(/(?:\r\n?|\n)/g);this._input=Tr+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Fn),this.offset-=Fn;var Un=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),qn.length-1&&(this.yylineno-=qn.length-1);var At=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:qn?(qn.length===Un.length?this.yylloc.first_column:0)+Un[Un.length-qn.length].length-qn[0].length:this.yylloc.first_column-Fn},this.options.ranges&&(this.yylloc.range=[At[0],At[0]+this.yyleng-Fn]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(Tr){this.unput(this.match.slice(Tr))},pastInput:function(){var Tr=this.matched.substr(0,this.matched.length-this.match.length);return(Tr.length>20?"...":"")+Tr.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var Tr=this.match;return Tr.length<20&&(Tr+=this._input.substr(0,20-Tr.length)),(Tr.substr(0,20)+(Tr.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var Tr=this.pastInput(),Fn=new Array(Tr.length+1).join("-");return Tr+this.upcomingInput()+` +`+Fn+"^"},test_match:function(Tr,Fn){var qn,Un,At;if(this.options.backtrack_lexer&&(At={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&&(At.yylloc.range=this.yylloc.range.slice(0))),Un=Tr[0].match(/(?:\r\n?|\n).*/g),Un&&(this.yylineno+=Un.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Un?Un[Un.length-1].length-Un[Un.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+Tr[0].length},this.yytext+=Tr[0],this.match+=Tr[0],this.matches=Tr,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(Tr[0].length),this.matched+=Tr[0],qn=this.performAction.call(this,this.yy,this,Fn,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),qn)return qn;if(this._backtrack){for(var wt in At)this[wt]=At[wt];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Tr,Fn,qn,Un;this._more||(this.yytext="",this.match="");for(var At=this._currentRules(),wt=0;wtFn[0].length)){if(Fn=qn,Un=wt,this.options.backtrack_lexer){if(Tr=this.test_match(qn,At[wt]),Tr!==!1)return Tr;if(this._backtrack){Fn=!1;continue}else return!1}else if(!this.options.flex)break}return Fn?(Tr=this.test_match(Fn,At[Un]),Tr!==!1?Tr:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var Fn=this.next();return Fn||this.lex()},begin:function(Fn){this.conditionStack.push(Fn)},popState:function(){var Fn=this.conditionStack.length-1;return Fn>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(Fn){return Fn=this.conditionStack.length-1-Math.abs(Fn||0),Fn>=0?this.conditionStack[Fn]:"INITIAL"},pushState:function(Fn){this.begin(Fn)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(Fn,qn,Un,At){switch(Un){case 0:return 53;case 1:return 54;case 2:return 55;case 3:return 56;case 4:break;case 5:break;case 6:return this.begin("acc_title"),31;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),33;case 9:return this.popState(),"acc_descr_value";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 70;case 22:this.popState();break;case 23:return 71;case 24:this.popState();break;case 25:return"STR";case 26:this.begin("string");break;case 27:return 73;case 28:return this.begin("namespace"),40;case 29:return this.popState(),8;case 30:break;case 31:return this.begin("namespace-body"),37;case 32:return this.popState(),39;case 33:return"EOF_IN_STRUCT";case 34:return 8;case 35:break;case 36:return"EDGE_STATE";case 37:return this.begin("class"),44;case 38:return this.popState(),8;case 39:break;case 40:return this.popState(),this.popState(),39;case 41:return this.begin("class-body"),37;case 42:return this.popState(),39;case 43:return"EOF_IN_STRUCT";case 44:return"EDGE_STATE";case 45:return"OPEN_IN_STRUCT";case 46:break;case 47:return"MEMBER";case 48:return 76;case 49:return 66;case 50:return 67;case 51:return 69;case 52:return 50;case 53:return 52;case 54:return 45;case 55:return 46;case 56:return 72;case 57:this.popState();break;case 58:return"GENERICTYPE";case 59:this.begin("generic");break;case 60:this.popState();break;case 61:return"BQUOTE_STR";case 62:this.begin("bqstring");break;case 63:return 68;case 64:return 68;case 65:return 68;case 66:return 68;case 67:return 60;case 68:return 60;case 69:return 62;case 70:return 62;case 71:return 61;case 72:return 59;case 73:return 63;case 74:return 64;case 75:return 65;case 76:return 21;case 77:return 42;case 78:return 95;case 79:return"DOT";case 80:return"PLUS";case 81:return 81;case 82:return 78;case 83:return 84;case 84:return 84;case 85:return 85;case 86:return"EQUALS";case 87:return"EQUALS";case 88:return 74;case 89:return 12;case 90:return 14;case 91:return"PUNCTUATION";case 92:return 80;case 93:return 97;case 94:return 83;case 95:return 83;case 96:return 9}},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)/,/^(?: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,32,33,34,35,36,37,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},namespace:{rules:[26,28,29,30,31,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},"class-body":{rules:[26,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},class:{rules:[26,38,39,40,41,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_descr:{rules:[9,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_title:{rules:[7,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},callback_args:{rules:[22,23,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},callback_name:{rules:[19,20,21,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},href:{rules:[26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},struct:{rules:[26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},generic:{rules:[26,48,49,50,51,52,53,54,55,56,57,58,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},bqstring:{rules:[26,48,49,50,51,52,53,54,55,56,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},string:{rules:[24,25,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,37,48,49,50,51,52,53,54,55,56,59,62,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],inclusive:!0}}};return ao}();xi.lexer=Ma;function zs(){this.yy={}}return zs.prototype=xi,xi.Parser=zs,new zs}();_ve.parser=_ve;const KGe=_ve,WGe=["#","+","~","-",""];class YGe{constructor(s,u){this.memberType=u,this.visibility="",this.classifier="";const d=Yf(s,qt());this.parseMember(d)}getDisplayDetails(){let s=this.visibility+qF(this.id);this.memberType==="method"&&(s+=`(${qF(this.parameters.trim())})`,this.returnType&&(s+=" : "+qF(this.returnType))),s=s.trim();const u=this.parseClassifier();return{displayText:s,cssStyle:u}}parseMember(s){let u="";if(this.memberType==="method"){const d=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/,p=s.match(d);if(p){const v=p[1]?p[1].trim():"";if(WGe.includes(v)&&(this.visibility=v),this.id=p[2].trim(),this.parameters=p[3]?p[3].trim():"",u=p[4]?p[4].trim():"",this.returnType=p[5]?p[5].trim():"",u===""){const b=this.returnType.substring(this.returnType.length-1);b.match(/[$*]/)&&(u=b,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{const d=s.length,p=s.substring(0,1),v=s.substring(d-1);WGe.includes(p)&&(this.visibility=p),v.match(/[$*]/)&&(u=v),this.id=s.substring(this.visibility===""?0:1,u===""?d:d-1)}this.classifier=u}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}}const mJ="classId-";let Ave=[],xh={},vJ=[],XGe=0,R9={},Lve=0,WR=[];const tS=i=>ci.sanitizeText(i,qt()),nS=function(i){const s=ci.sanitizeText(i,qt());let u="",d=s;if(s.indexOf("~")>0){const p=s.split("~");d=tS(p[0]),u=tS(p[1])}return{className:d,type:u}},Ein=function(i,s){const u=ci.sanitizeText(i,qt());s&&(s=tS(s));const{className:d}=nS(u);xh[d].label=s},wJ=function(i){const s=ci.sanitizeText(i,qt()),{className:u,type:d}=nS(s);if(Object.hasOwn(xh,u))return;const p=ci.sanitizeText(u,qt());xh[p]={id:p,type:d,label:p,cssClasses:[],methods:[],members:[],annotations:[],styles:[],domId:mJ+p+"-"+XGe},XGe++},QGe=function(i){const s=ci.sanitizeText(i,qt());if(s in xh)return xh[s].domId;throw new Error("Class not found: "+s)},Tin=function(){Ave=[],xh={},vJ=[],WR=[],WR.push(ZGe),R9={},Lve=0,Pg()},Cin=function(i){return xh[i]},Sin=function(){return xh},_in=function(){return Ave},Ain=function(){return vJ},Lin=function(i){Xe.debug("Adding relation: "+JSON.stringify(i)),wJ(i.id1),wJ(i.id2),i.id1=nS(i.id1).className,i.id2=nS(i.id2).className,i.relationTitle1=ci.sanitizeText(i.relationTitle1.trim(),qt()),i.relationTitle2=ci.sanitizeText(i.relationTitle2.trim(),qt()),Ave.push(i)},Min=function(i,s){const u=nS(i).className;xh[u].annotations.push(s)},JGe=function(i,s){wJ(i);const u=nS(i).className,d=xh[u];if(typeof s=="string"){const p=s.trim();p.startsWith("<<")&&p.endsWith(">>")?d.annotations.push(tS(p.substring(2,p.length-2))):p.indexOf(")")>0?d.methods.push(new YGe(p,"method")):p&&d.members.push(new YGe(p,"attribute"))}},Din=function(i,s){Array.isArray(s)&&(s.reverse(),s.forEach(u=>JGe(i,u)))},Iin=function(i,s){const u={id:`note${vJ.length}`,class:s,text:i};vJ.push(u)},Oin=function(i){return i.startsWith(":")&&(i=i.substring(1)),tS(i.trim())},Mve=function(i,s){i.split(",").forEach(function(u){let d=u;u[0].match(/\d/)&&(d=mJ+d),xh[d]!==void 0&&xh[d].cssClasses.push(s)})},Nin=function(i,s){i.split(",").forEach(function(u){s!==void 0&&(xh[u].tooltip=tS(s))})},Pin=function(i,s){return s?R9[s].classes[i].tooltip:xh[i].tooltip},Bin=function(i,s,u){const d=qt();i.split(",").forEach(function(p){let v=p;p[0].match(/\d/)&&(v=mJ+v),xh[v]!==void 0&&(xh[v].link=Ao.formatUrl(s,d),d.securityLevel==="sandbox"?xh[v].linkTarget="_top":typeof u=="string"?xh[v].linkTarget=tS(u):xh[v].linkTarget="_blank")}),Mve(i,"clickable")},Fin=function(i,s,u){i.split(",").forEach(function(d){Rin(d,s,u),xh[d].haveCallback=!0}),Mve(i,"clickable")},Rin=function(i,s,u){const d=ci.sanitizeText(i,qt());if(qt().securityLevel!=="loose"||s===void 0)return;const v=d;if(xh[v]!==void 0){const b=QGe(v);let y=[];if(typeof u=="string"){y=u.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let T=0;T")),p.classed("hover",!0)}).on("mouseout",function(){s.transition().duration(500).style("opacity",0),Ir(this).classed("hover",!1)})};WR.push(ZGe);let eKe="TB";const yJ={setAccTitle:Bg,getAccTitle:Cp,getAccDescription:_p,setAccDescription:Sp,getConfig:()=>qt().class,addClass:wJ,bindFunctions:jin,clear:Tin,getClass:Cin,getClasses:Sin,getNotes:Ain,addAnnotation:Min,addNote:Iin,getRelations:_in,addRelation:Lin,getDirection:()=>eKe,setDirection:i=>{eKe=i},addMember:JGe,addMembers:Din,cleanupLabel:Oin,lineType:$in,relationType:zin,setClickEvent:Fin,setCssClass:Mve,setLink:Bin,getTooltip:Pin,setTooltip:Nin,lookUpDomId:QGe,setDiagramTitle:cm,getDiagramTitle:Ap,setClassLabel:Ein,addNamespace:function(i){R9[i]===void 0&&(R9[i]={id:i,classes:{},children:{},domId:mJ+i+"-"+Lve},Lve++)},addClassesToNamespace:function(i,s){if(R9[i]!==void 0)for(const u of s){const{className:d}=nS(u);xh[d].parent=i,R9[i].classes[d]=xh[d]}},getNamespace:function(i){return R9[i]},getNamespaces:function(){return R9},setCssStyle:function(i,s){const u=xh[i];if(!(!s||!u))for(const d of s)d.includes(",")?u.styles.push(...d.split(",")):u.styles.push(d)}},tKe=i=>`g.classGroup text { + fill: ${i.nodeBorder||i.classText}; + stroke: none; + font-family: ${i.fontFamily}; + font-size: 10px; + + .title { + font-weight: bolder; + } + +} + +.nodeLabel, .edgeLabel { + color: ${i.classText}; +} +.edgeLabel .label rect { + fill: ${i.mainBkg}; +} +.label text { + fill: ${i.classText}; +} +.edgeLabel .label span { + background: ${i.mainBkg}; +} + +.classTitle { + font-weight: bolder; +} +.node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${i.mainBkg}; + stroke: ${i.nodeBorder}; + stroke-width: 1px; + } + + +.divider { + stroke: ${i.nodeBorder}; + stroke-width: 1; +} + +g.clickable { + cursor: pointer; +} + +g.classGroup rect { + fill: ${i.mainBkg}; + stroke: ${i.nodeBorder}; +} + +g.classGroup line { + stroke: ${i.nodeBorder}; + stroke-width: 1; +} + +.classLabel .box { + stroke: none; + stroke-width: 0; + fill: ${i.mainBkg}; + opacity: 0.5; +} + +.classLabel .label { + fill: ${i.nodeBorder}; + font-size: 10px; +} + +.relation { + stroke: ${i.lineColor}; + stroke-width: 1; + fill: none; +} + +.dashed-line{ + stroke-dasharray: 3; +} + +.dotted-line{ + stroke-dasharray: 1 2; +} + +#compositionStart, .composition { + fill: ${i.lineColor} !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#compositionEnd, .composition { + fill: ${i.lineColor} !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${i.lineColor} !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${i.lineColor} !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#extensionStart, .extension { + fill: transparent !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#extensionEnd, .extension { + fill: transparent !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#aggregationStart, .aggregation { + fill: transparent !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#aggregationEnd, .aggregation { + fill: transparent !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#lollipopStart, .lollipop { + fill: ${i.mainBkg} !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +#lollipopEnd, .lollipop { + fill: ${i.mainBkg} !important; + stroke: ${i.lineColor} !important; + stroke-width: 1; +} + +.edgeTerminals { + font-size: 11px; + line-height: initial; +} + +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.textColor}; +} +`;let nKe=0;const qin=function(i,s,u,d,p){const v=function(oe){switch(oe){case p.db.relationType.AGGREGATION:return"aggregation";case p.db.relationType.EXTENSION:return"extension";case p.db.relationType.COMPOSITION:return"composition";case p.db.relationType.DEPENDENCY:return"dependency";case p.db.relationType.LOLLIPOP:return"lollipop"}};s.points=s.points.filter(oe=>!Number.isNaN(oe.y));const b=s.points,y=k7().x(function(oe){return oe.x}).y(function(oe){return oe.y}).curve(FF),T=i.append("path").attr("d",y(b)).attr("id","edge"+nKe).attr("class","relation");let _="";d.arrowMarkerAbsolute&&(_=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,_=_.replace(/\(/g,"\\("),_=_.replace(/\)/g,"\\)")),u.relation.lineType==1&&T.attr("class","relation dashed-line"),u.relation.lineType==10&&T.attr("class","relation dotted-line"),u.relation.type1!=="none"&&T.attr("marker-start","url("+_+"#"+v(u.relation.type1)+"Start)"),u.relation.type2!=="none"&&T.attr("marker-end","url("+_+"#"+v(u.relation.type2)+"End)");let A,P;const R=s.points.length;let F=Ao.calcLabelPosition(s.points);A=F.x,P=F.y;let j,K,ee,ie;if(R%2!==0&&R>1){let oe=Ao.calcCardinalityPosition(u.relation.type1!=="none",s.points,s.points[0]),pe=Ao.calcCardinalityPosition(u.relation.type2!=="none",s.points,s.points[R-1]);Xe.debug("cardinality_1_point "+JSON.stringify(oe)),Xe.debug("cardinality_2_point "+JSON.stringify(pe)),j=oe.x,K=oe.y,ee=pe.x,ie=pe.y}if(u.title!==void 0){const oe=i.append("g").attr("class","classLabel"),pe=oe.append("text").attr("class","label").attr("x",A).attr("y",P).attr("fill","red").attr("text-anchor","middle").text(u.title);window.label=pe;const be=pe.node().getBBox();oe.insert("rect",":first-child").attr("class","box").attr("x",be.x-d.padding/2).attr("y",be.y-d.padding/2).attr("width",be.width+d.padding).attr("height",be.height+d.padding)}Xe.info("Rendering relation "+JSON.stringify(u)),u.relationTitle1!==void 0&&u.relationTitle1!=="none"&&i.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",j).attr("y",K).attr("fill","black").attr("font-size","6").text(u.relationTitle1),u.relationTitle2!==void 0&&u.relationTitle2!=="none"&&i.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",ee).attr("y",ie).attr("fill","black").attr("font-size","6").text(u.relationTitle2),nKe++},Hin=function(i,s,u,d){Xe.debug("Rendering class ",s,u);const p=s.id,v={id:p,label:s.id,width:0,height:0},b=i.append("g").attr("id",d.db.lookUpDomId(p)).attr("class","classGroup");let y;s.link?y=b.append("svg:a").attr("xlink:href",s.link).attr("target",s.linkTarget).append("text").attr("y",u.textHeight+u.padding).attr("x",0):y=b.append("text").attr("y",u.textHeight+u.padding).attr("x",0);let T=!0;s.annotations.forEach(function(pe){const be=y.append("tspan").text("«"+pe+"»");T||be.attr("dy",u.textHeight),T=!1});let _=rKe(s);const A=y.append("tspan").text(_).attr("class","title");T||A.attr("dy",u.textHeight);const P=y.node().getBBox().height;let R,F,j;if(s.members.length>0){R=b.append("line").attr("x1",0).attr("y1",u.padding+P+u.dividerMargin/2).attr("y2",u.padding+P+u.dividerMargin/2);const pe=b.append("text").attr("x",u.padding).attr("y",P+u.dividerMargin+u.textHeight).attr("fill","white").attr("class","classText");T=!0,s.members.forEach(function(be){iKe(pe,be,T,u),T=!1}),F=pe.node().getBBox()}if(s.methods.length>0){j=b.append("line").attr("x1",0).attr("y1",u.padding+P+u.dividerMargin+F.height).attr("y2",u.padding+P+u.dividerMargin+F.height);const pe=b.append("text").attr("x",u.padding).attr("y",P+2*u.dividerMargin+F.height+u.textHeight).attr("fill","white").attr("class","classText");T=!0,s.methods.forEach(function(be){iKe(pe,be,T,u),T=!1})}const K=b.node().getBBox();var ee=" ";s.cssClasses.length>0&&(ee=ee+s.cssClasses.join(" "));const oe=b.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",K.width+2*u.padding).attr("height",K.height+u.padding+.5*u.dividerMargin).attr("class",ee).node().getBBox().width;return y.node().childNodes.forEach(function(pe){pe.setAttribute("x",(oe-pe.getBBox().width)/2)}),s.tooltip&&y.insert("title").text(s.tooltip),R&&R.attr("x2",oe),j&&j.attr("x2",oe),v.width=oe,v.height=K.height+u.padding+.5*u.dividerMargin,v},rKe=function(i){let s=i.id;return i.type&&(s+="<"+qF(i.type)+">"),s},Vin=function(i,s,u,d){Xe.debug("Rendering note ",s,u);const p=s.id,v={id:p,text:s.text,width:0,height:0},b=i.append("g").attr("id",p).attr("class","classGroup");let y=b.append("text").attr("y",u.textHeight+u.padding).attr("x",0);const T=JSON.parse(`"${s.text}"`).split(` +`);T.forEach(function(R){Xe.debug(`Adding line: ${R}`),y.append("tspan").text(R).attr("class","title").attr("dy",u.textHeight)});const _=b.node().getBBox(),P=b.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",_.width+2*u.padding).attr("height",_.height+T.length*u.textHeight+u.padding+.5*u.dividerMargin).node().getBBox().width;return y.node().childNodes.forEach(function(R){R.setAttribute("x",(P-R.getBBox().width)/2)}),v.width=P,v.height=_.height+T.length*u.textHeight+u.padding+.5*u.dividerMargin,v},iKe=function(i,s,u,d){const{displayText:p,cssStyle:v}=s.getDisplayDetails(),b=i.append("tspan").attr("x",d.padding).text(p);v!==""&&b.attr("style",s.cssStyle),u||b.attr("dy",d.textHeight)},Dve={getClassTitleString:rKe,drawClass:Hin,drawEdge:qin,drawNote:Vin};let xJ={};const kJ=20,YR=function(i){const s=Object.entries(xJ).find(u=>u[1].label===i);if(s)return s[0]},Uin=function(i){i.append("defs").append("marker").attr("id","extensionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),i.append("defs").append("marker").attr("id","extensionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z"),i.append("defs").append("marker").attr("id","compositionStart").attr("class","extension").attr("refX",0).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"),i.append("defs").append("marker").attr("id","compositionEnd").attr("refX",19).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"),i.append("defs").append("marker").attr("id","aggregationStart").attr("class","extension").attr("refX",0).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"),i.append("defs").append("marker").attr("id","aggregationEnd").attr("refX",19).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"),i.append("defs").append("marker").attr("id","dependencyStart").attr("class","extension").attr("refX",0).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"),i.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 18,7 L9,13 L14,7 L9,1 Z")},Gin=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:KGe,db:yJ,renderer:{draw:function(i,s,u,d){const p=qt().class;xJ={},Xe.info("Rendering diagram "+i);const v=qt().securityLevel;let b;v==="sandbox"&&(b=Ir("#i"+s));const y=Ir(v==="sandbox"?b.nodes()[0].contentDocument.body:"body"),T=y.select(`[id='${s}']`);Uin(T);const _=new B0({multigraph:!0});_.setGraph({isMultiGraph:!0}),_.setDefaultEdgeLabel(function(){return{}});const A=d.db.getClasses(),P=Object.keys(A);for(const oe of P){const pe=A[oe],be=Dve.drawClass(T,pe,p,d);xJ[be.id]=be,_.setNode(be.id,be),Xe.info("Org height: "+be.height)}d.db.getRelations().forEach(function(oe){Xe.info("tjoho"+YR(oe.id1)+YR(oe.id2)+JSON.stringify(oe)),_.setEdge(YR(oe.id1),YR(oe.id2),{relation:oe},oe.title||"DEFAULT")}),d.db.getNotes().forEach(function(oe){Xe.debug(`Adding note: ${JSON.stringify(oe)}`);const pe=Dve.drawNote(T,oe,p,d);xJ[pe.id]=pe,_.setNode(pe.id,pe),oe.class&&oe.class in A&&_.setEdge(oe.id,YR(oe.class),{relation:{id1:oe.id,id2:oe.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")}),qD(_),_.nodes().forEach(function(oe){oe!==void 0&&_.node(oe)!==void 0&&(Xe.debug("Node "+oe+": "+JSON.stringify(_.node(oe))),y.select("#"+(d.db.lookUpDomId(oe)||oe)).attr("transform","translate("+(_.node(oe).x-_.node(oe).width/2)+","+(_.node(oe).y-_.node(oe).height/2)+" )"))}),_.edges().forEach(function(oe){oe!==void 0&&_.edge(oe)!==void 0&&(Xe.debug("Edge "+oe.v+" -> "+oe.w+": "+JSON.stringify(_.edge(oe))),Dve.drawEdge(T,_.edge(oe),_.edge(oe).relation,p,d))});const j=T.node().getBBox(),K=j.width+kJ*2,ee=j.height+kJ*2;Ng(T,ee,K,p.useMaxWidth);const ie=`${j.x-kJ} ${j.y-kJ} ${K} ${ee}`;Xe.debug(`viewBox ${ie}`),T.attr("viewBox",ie)}},styles:tKe,init:i=>{i.class||(i.class={}),i.class.arrowMarkerAbsolute=i.arrowMarkerAbsolute,yJ.clear()}}},Symbol.toStringTag,{value:"Module"})),Ive=i=>ci.sanitizeText(i,qt());let Ove={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const Kin=function(i,s,u,d){const p=Object.keys(i);Xe.info("keys:",p),Xe.info(i),p.forEach(function(v){var _,A;const b=i[v],T={shape:"rect",id:b.id,domId:b.domId,labelText:Ive(b.id),labelStyle:"",style:"fill: none; stroke: black",padding:((_=qt().flowchart)==null?void 0:_.padding)??((A=qt().class)==null?void 0:A.padding)};s.setNode(b.id,T),sKe(b.classes,s,u,d,b.id),Xe.info("setNode",T)})},sKe=function(i,s,u,d,p){const v=Object.keys(i);Xe.info("keys:",v),Xe.info(i),v.filter(b=>i[b].parent==p).forEach(function(b){var j,K;const y=i[b],T=y.cssClasses.join(" "),_=om(y.styles),A=y.label??y.id,P=0,R="class_box",F={labelStyle:_.labelStyle,shape:R,labelText:Ive(A),classData:y,rx:P,ry:P,class:T,style:_.style,id:y.id,domId:y.domId,tooltip:d.db.getTooltip(y.id,p)||"",haveCallback:y.haveCallback,link:y.link,width:y.type==="group"?500:void 0,type:y.type,padding:((j=qt().flowchart)==null?void 0:j.padding)??((K=qt().class)==null?void 0:K.padding)};s.setNode(y.id,F),p&&s.setParent(y.id,p),Xe.info("setNode",F)})},Win=function(i,s,u,d){Xe.info(i),i.forEach(function(p,v){var K,ee;const b=p,y="",T={labelStyle:"",style:""},_=b.text,A=0,P="note",R={labelStyle:T.labelStyle,shape:P,labelText:Ive(_),noteData:b,rx:A,ry:A,class:y,style:T.style,id:b.id,domId:b.id,tooltip:"",type:"note",padding:((K=qt().flowchart)==null?void 0:K.padding)??((ee=qt().class)==null?void 0:ee.padding)};if(s.setNode(b.id,R),Xe.info("setNode",R),!b.class||!(b.class in d))return;const F=u+v,j={id:`edgeNote${F}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:Ov(Ove.curve,kp)};s.setEdge(b.id,b.class,j,F)})},Yin=function(i,s){const u=qt().flowchart;let d=0;i.forEach(function(p){var b;d++;const v={classes:"relation",pattern:p.relation.lineType==1?"dashed":"solid",id:`id_${p.id1}_${p.id2}_${d}`,arrowhead:p.type==="arrow_open"?"none":"normal",startLabelRight:p.relationTitle1==="none"?"":p.relationTitle1,endLabelLeft:p.relationTitle2==="none"?"":p.relationTitle2,arrowTypeStart:aKe(p.relation.type1),arrowTypeEnd:aKe(p.relation.type2),style:"fill:none",labelStyle:"",curve:Ov(u==null?void 0:u.curve,kp)};if(Xe.info(v,p),p.style!==void 0){const y=om(p.style);v.style=y.style,v.labelStyle=y.labelStyle}p.text=p.title,p.text===void 0?p.style!==void 0&&(v.arrowheadStyle="fill: #333"):(v.arrowheadStyle="fill: #333",v.labelpos="c",((b=qt().flowchart)==null?void 0:b.htmlLabels)??qt().htmlLabels?(v.labelType="html",v.label=''+p.text+""):(v.labelType="text",v.label=p.text.replace(ci.lineBreakRegex,` +`),p.style===void 0&&(v.style=v.style||"stroke: #333; stroke-width: 1.5px;fill:none"),v.labelStyle=v.labelStyle.replace("color:","fill:"))),s.setEdge(p.id1,p.id2,v,d)})},Xin=function(i){Ove={...Ove,...i}},Qin=async function(i,s,u,d){Xe.info("Drawing class - ",s);const p=qt().flowchart??qt().class,v=qt().securityLevel;Xe.info("config:",p);const b=(p==null?void 0:p.nodeSpacing)??50,y=(p==null?void 0:p.rankSpacing)??50,T=new B0({multigraph:!0,compound:!0}).setGraph({rankdir:d.db.getDirection(),nodesep:b,ranksep:y,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}}),_=d.db.getNamespaces(),A=d.db.getClasses(),P=d.db.getRelations(),R=d.db.getNotes();Xe.info(P),Kin(_,T,s,d),sKe(A,T,s,d),Yin(P,T),Win(R,T,P.length+1,A);let F;v==="sandbox"&&(F=Ir("#i"+s));const j=Ir(v==="sandbox"?F.nodes()[0].contentDocument.body:"body"),K=j.select(`[id="${s}"]`),ee=j.select("#"+s+" g");if(await qme(ee,T,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",s),Ao.insertTitle(K,"classTitleText",(p==null?void 0:p.titleTopMargin)??5,d.db.getDiagramTitle()),y9(T,K,p==null?void 0:p.diagramPadding,p==null?void 0:p.useMaxWidth),!(p!=null&&p.htmlLabels)){const ie=v==="sandbox"?F.nodes()[0].contentDocument:document,oe=ie.querySelectorAll('[id="'+s+'"] .edgeLabel .label');for(const pe of oe){const be=pe.getBBox(),ae=ie.createElementNS("http://www.w3.org/2000/svg","rect");ae.setAttribute("rx",0),ae.setAttribute("ry",0),ae.setAttribute("width",be.width),ae.setAttribute("height",be.height),pe.insertBefore(ae,pe.firstChild)}}};function aKe(i){let s;switch(i){case 0:s="aggregation";break;case 1:s="extension";break;case 2:s="composition";break;case 3:s="dependency";break;case 4:s="lollipop";break;default:s="none"}return s}const Jin=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:KGe,db:yJ,renderer:{setConf:Xin,draw:Qin},styles:tKe,init:i=>{i.class||(i.class={}),i.class.arrowMarkerAbsolute=i.arrowMarkerAbsolute,yJ.clear()}}},Symbol.toStringTag,{value:"Module"}));var Nve=function(){var i=function(Ie,Se,Ce,ke){for(Ce=Ce||{},ke=Ie.length;ke--;Ce[Ie[ke]]=Se);return Ce},s=[1,2],u=[1,3],d=[1,4],p=[2,4],v=[1,9],b=[1,11],y=[1,15],T=[1,16],_=[1,17],A=[1,18],P=[1,30],R=[1,19],F=[1,20],j=[1,21],K=[1,22],ee=[1,23],ie=[1,25],oe=[1,26],pe=[1,27],be=[1,28],ae=[1,29],ne=[1,32],se=[1,33],de=[1,34],X=[1,35],ge=[1,31],W=[1,4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],xe=[1,4,5,13,14,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],U=[4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],Fe={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,cssClassStatement:11,idStatement:12,DESCR:13,"-->":14,HIDE_EMPTY:15,scale:16,WIDTH:17,COMPOSIT_STATE:18,STRUCT_START:19,STRUCT_STOP:20,STATE_DESCR:21,AS:22,ID:23,FORK:24,JOIN:25,CHOICE:26,CONCURRENT:27,note:28,notePosition:29,NOTE_TEXT:30,direction:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,classDef:37,CLASSDEF_ID:38,CLASSDEF_STYLEOPTS:39,DEFAULT:40,class:41,CLASSENTITY_IDS:42,STYLECLASS:43,direction_tb:44,direction_bt:45,direction_rl:46,direction_lr:47,eol:48,";":49,EDGE_STATE:50,STYLE_SEPARATOR:51,left_of:52,right_of:53,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",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",30:"NOTE_TEXT",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:"class",42:"CLASSENTITY_IDS",43:"STYLECLASS",44:"direction_tb",45:"direction_bt",46:"direction_rl",47:"direction_lr",49:";",50:"EDGE_STATE",51:"STYLE_SEPARATOR",52:"left_of",53:"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,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],[31,1],[31,1],[31,1],[31,1],[48,1],[48,1],[12,1],[12,1],[12,3],[12,3],[29,1],[29,1]],performAction:function(Se,Ce,ke,Ke,Ft,Ne,gn){var _t=Ne.length-1;switch(Ft){case 3:return Ke.setRootDoc(Ne[_t]),Ne[_t];case 4:this.$=[];break;case 5:Ne[_t]!="nl"&&(Ne[_t-1].push(Ne[_t]),this.$=Ne[_t-1]);break;case 6:case 7:this.$=Ne[_t];break;case 8:this.$="nl";break;case 11:this.$=Ne[_t];break;case 12:const xt=Ne[_t-1];xt.description=Ke.trimColon(Ne[_t]),this.$=xt;break;case 13:this.$={stmt:"relation",state1:Ne[_t-2],state2:Ne[_t]};break;case 14:const Pt=Ke.trimColon(Ne[_t]);this.$={stmt:"relation",state1:Ne[_t-3],state2:Ne[_t-1],description:Pt};break;case 18:this.$={stmt:"state",id:Ne[_t-3],type:"default",description:"",doc:Ne[_t-1]};break;case 19:var Et=Ne[_t],Gt=Ne[_t-2].trim();if(Ne[_t].match(":")){var ln=Ne[_t].split(":");Et=ln[0],Gt=[Gt,ln[1]]}this.$={stmt:"state",id:Et,type:"default",description:Gt};break;case 20:this.$={stmt:"state",id:Ne[_t-3],type:"default",description:Ne[_t-5],doc:Ne[_t-1]};break;case 21:this.$={stmt:"state",id:Ne[_t],type:"fork"};break;case 22:this.$={stmt:"state",id:Ne[_t],type:"join"};break;case 23:this.$={stmt:"state",id:Ne[_t],type:"choice"};break;case 24:this.$={stmt:"state",id:Ke.getDividerId(),type:"divider"};break;case 25:this.$={stmt:"state",id:Ne[_t-1].trim(),note:{position:Ne[_t-2].trim(),text:Ne[_t].trim()}};break;case 28:this.$=Ne[_t].trim(),Ke.setAccTitle(this.$);break;case 29:case 30:this.$=Ne[_t].trim(),Ke.setAccDescription(this.$);break;case 31:case 32:this.$={stmt:"classDef",id:Ne[_t-1].trim(),classes:Ne[_t].trim()};break;case 33:this.$={stmt:"applyClass",id:Ne[_t-1].trim(),styleClass:Ne[_t].trim()};break;case 34:Ke.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 35:Ke.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 36:Ke.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 37:Ke.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 40:case 41:this.$={stmt:"state",id:Ne[_t].trim(),type:"default",description:""};break;case 42:this.$={stmt:"state",id:Ne[_t-2].trim(),classes:[Ne[_t].trim()],type:"default",description:""};break;case 43:this.$={stmt:"state",id:Ne[_t-2].trim(),classes:[Ne[_t].trim()],type:"default",description:""};break}},table:[{3:1,4:s,5:u,6:d},{1:[3]},{3:5,4:s,5:u,6:d},{3:6,4:s,5:u,6:d},i([1,4,5,15,16,18,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],p,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:v,5:b,8:8,9:10,10:12,11:13,12:14,15:y,16:T,18:_,21:A,23:P,24:R,25:F,26:j,27:K,28:ee,31:24,32:ie,34:oe,36:pe,37:be,41:ae,44:ne,45:se,46:de,47:X,50:ge},i(W,[2,5]),{9:36,10:12,11:13,12:14,15:y,16:T,18:_,21:A,23:P,24:R,25:F,26:j,27:K,28:ee,31:24,32:ie,34:oe,36:pe,37:be,41:ae,44:ne,45:se,46:de,47:X,50:ge},i(W,[2,7]),i(W,[2,8]),i(W,[2,9]),i(W,[2,10]),i(W,[2,11],{13:[1,37],14:[1,38]}),i(W,[2,15]),{17:[1,39]},i(W,[2,17],{19:[1,40]}),{22:[1,41]},i(W,[2,21]),i(W,[2,22]),i(W,[2,23]),i(W,[2,24]),{29:42,30:[1,43],52:[1,44],53:[1,45]},i(W,[2,27]),{33:[1,46]},{35:[1,47]},i(W,[2,30]),{38:[1,48],40:[1,49]},{42:[1,50]},i(xe,[2,40],{51:[1,51]}),i(xe,[2,41],{51:[1,52]}),i(W,[2,34]),i(W,[2,35]),i(W,[2,36]),i(W,[2,37]),i(W,[2,6]),i(W,[2,12]),{12:53,23:P,50:ge},i(W,[2,16]),i(U,p,{7:54}),{23:[1,55]},{23:[1,56]},{22:[1,57]},{23:[2,44]},{23:[2,45]},i(W,[2,28]),i(W,[2,29]),{39:[1,58]},{39:[1,59]},{43:[1,60]},{23:[1,61]},{23:[1,62]},i(W,[2,13],{13:[1,63]}),{4:v,5:b,8:8,9:10,10:12,11:13,12:14,15:y,16:T,18:_,20:[1,64],21:A,23:P,24:R,25:F,26:j,27:K,28:ee,31:24,32:ie,34:oe,36:pe,37:be,41:ae,44:ne,45:se,46:de,47:X,50:ge},i(W,[2,19],{19:[1,65]}),{30:[1,66]},{23:[1,67]},i(W,[2,31]),i(W,[2,32]),i(W,[2,33]),i(xe,[2,42]),i(xe,[2,43]),i(W,[2,14]),i(W,[2,18]),i(U,p,{7:68}),i(W,[2,25]),i(W,[2,26]),{4:v,5:b,8:8,9:10,10:12,11:13,12:14,15:y,16:T,18:_,20:[1,69],21:A,23:P,24:R,25:F,26:j,27:K,28:ee,31:24,32:ie,34:oe,36:pe,37:be,41:ae,44:ne,45:se,46:de,47:X,50:ge},i(W,[2,20])],defaultActions:{5:[2,1],6:[2,2],44:[2,44],45:[2,45]},parseError:function(Se,Ce){if(Ce.recoverable)this.trace(Se);else{var ke=new Error(Se);throw ke.hash=Ce,ke}},parse:function(Se){var Ce=this,ke=[0],Ke=[],Ft=[null],Ne=[],gn=this.table,_t="",Et=0,Gt=0,ln=2,xt=1,Pt=Ne.slice.call(arguments,1),Qe=Object.create(this.lexer),Dt={yy:{}};for(var kt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,kt)&&(Dt.yy[kt]=this.yy[kt]);Qe.setInput(Se,Dt.yy),Dt.yy.lexer=Qe,Dt.yy.parser=this,typeof Qe.yylloc>"u"&&(Qe.yylloc={});var On=Qe.yylloc;Ne.push(On);var ht=Qe.options&&Qe.options.ranges;typeof Dt.yy.parseError=="function"?this.parseError=Dt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function zr(){var At;return At=Ke.pop()||Qe.lex()||xt,typeof At!="number"&&(At instanceof Array&&(Ke=At,At=Ke.pop()),At=Ce.symbols_[At]||At),At}for(var yt,ji,xi,Ma,zs={},ao,Tr,Fn,qn;;){if(ji=ke[ke.length-1],this.defaultActions[ji]?xi=this.defaultActions[ji]:((yt===null||typeof yt>"u")&&(yt=zr()),xi=gn[ji]&&gn[ji][yt]),typeof xi>"u"||!xi.length||!xi[0]){var Un="";qn=[];for(ao in gn[ji])this.terminals_[ao]&&ao>ln&&qn.push("'"+this.terminals_[ao]+"'");Qe.showPosition?Un="Parse error on line "+(Et+1)+`: +`+Qe.showPosition()+` +Expecting `+qn.join(", ")+", got '"+(this.terminals_[yt]||yt)+"'":Un="Parse error on line "+(Et+1)+": Unexpected "+(yt==xt?"end of input":"'"+(this.terminals_[yt]||yt)+"'"),this.parseError(Un,{text:Qe.match,token:this.terminals_[yt]||yt,line:Qe.yylineno,loc:On,expected:qn})}if(xi[0]instanceof Array&&xi.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ji+", token: "+yt);switch(xi[0]){case 1:ke.push(yt),Ft.push(Qe.yytext),Ne.push(Qe.yylloc),ke.push(xi[1]),yt=null,Gt=Qe.yyleng,_t=Qe.yytext,Et=Qe.yylineno,On=Qe.yylloc;break;case 2:if(Tr=this.productions_[xi[1]][1],zs.$=Ft[Ft.length-Tr],zs._$={first_line:Ne[Ne.length-(Tr||1)].first_line,last_line:Ne[Ne.length-1].last_line,first_column:Ne[Ne.length-(Tr||1)].first_column,last_column:Ne[Ne.length-1].last_column},ht&&(zs._$.range=[Ne[Ne.length-(Tr||1)].range[0],Ne[Ne.length-1].range[1]]),Ma=this.performAction.apply(zs,[_t,Gt,Et,Dt.yy,xi[1],Ft,Ne].concat(Pt)),typeof Ma<"u")return Ma;Tr&&(ke=ke.slice(0,-1*Tr*2),Ft=Ft.slice(0,-1*Tr),Ne=Ne.slice(0,-1*Tr)),ke.push(this.productions_[xi[1]][0]),Ft.push(zs.$),Ne.push(zs._$),Fn=gn[ke[ke.length-2]][ke[ke.length-1]],ke.push(Fn);break;case 3:return!0}}return!0}},Pe=function(){var Ie={EOF:1,parseError:function(Ce,ke){if(this.yy.parser)this.yy.parser.parseError(Ce,ke);else throw new Error(Ce)},setInput:function(Se,Ce){return this.yy=Ce||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},input:function(){var Se=this._input[0];this.yytext+=Se,this.yyleng++,this.offset++,this.match+=Se,this.matched+=Se;var Ce=Se.match(/(?:\r\n?|\n).*/g);return Ce?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Se},unput:function(Se){var Ce=Se.length,ke=Se.split(/(?:\r\n?|\n)/g);this._input=Se+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Ce),this.offset-=Ce;var Ke=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),ke.length-1&&(this.yylineno-=ke.length-1);var Ft=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:ke?(ke.length===Ke.length?this.yylloc.first_column:0)+Ke[Ke.length-ke.length].length-ke[0].length:this.yylloc.first_column-Ce},this.options.ranges&&(this.yylloc.range=[Ft[0],Ft[0]+this.yyleng-Ce]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(Se){this.unput(this.match.slice(Se))},pastInput:function(){var Se=this.matched.substr(0,this.matched.length-this.match.length);return(Se.length>20?"...":"")+Se.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var Se=this.pastInput(),Ce=new Array(Se.length+1).join("-");return Se+this.upcomingInput()+` +`+Ce+"^"},test_match:function(Se,Ce){var ke,Ke,Ft;if(this.options.backtrack_lexer&&(Ft={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&&(Ft.yylloc.range=this.yylloc.range.slice(0))),Ke=Se[0].match(/(?:\r\n?|\n).*/g),Ke&&(this.yylineno+=Ke.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Ke?Ke[Ke.length-1].length-Ke[Ke.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],ke=this.performAction.call(this,this.yy,this,Ce,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ke)return ke;if(this._backtrack){for(var Ne in Ft)this[Ne]=Ft[Ne];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Se,Ce,ke,Ke;this._more||(this.yytext="",this.match="");for(var Ft=this._currentRules(),Ne=0;NeCe[0].length)){if(Ce=ke,Ke=Ne,this.options.backtrack_lexer){if(Se=this.test_match(ke,Ft[Ne]),Se!==!1)return Se;if(this._backtrack){Ce=!1;continue}else return!1}else if(!this.options.flex)break}return Ce?(Se=this.test_match(Ce,Ft[Ke]),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})},lex:function(){var Ce=this.next();return Ce||this.lex()},begin:function(Ce){this.conditionStack.push(Ce)},popState:function(){var Ce=this.conditionStack.length-1;return Ce>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(Ce){return Ce=this.conditionStack.length-1-Math.abs(Ce||0),Ce>=0?this.conditionStack[Ce]:"INITIAL"},pushState:function(Ce){this.begin(Ce)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(Ce,ke,Ke,Ft){switch(Ke){case 0:return 40;case 1:return 44;case 2:return 45;case 3:return 46;case 4:return 47;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"),16;case 13:return 17;case 14:this.popState();break;case 15:return this.begin("acc_title"),32;case 16:return this.popState(),"acc_title_value";case 17:return this.begin("acc_descr"),34;case 18:return this.popState(),"acc_descr_value";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"),37;case 23:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 24:return this.popState(),this.pushState("CLASSDEFID"),38;case 25:return this.popState(),39;case 26:return this.pushState("CLASS"),41;case 27:return this.popState(),this.pushState("CLASS_STYLE"),42;case 28:return this.popState(),43;case 29:return this.pushState("SCALE"),16;case 30:return 17;case 31:this.popState();break;case 32:this.pushState("STATE");break;case 33:return this.popState(),ke.yytext=ke.yytext.slice(0,-8).trim(),24;case 34:return this.popState(),ke.yytext=ke.yytext.slice(0,-8).trim(),25;case 35:return this.popState(),ke.yytext=ke.yytext.slice(0,-10).trim(),26;case 36:return this.popState(),ke.yytext=ke.yytext.slice(0,-8).trim(),24;case 37:return this.popState(),ke.yytext=ke.yytext.slice(0,-8).trim(),25;case 38:return this.popState(),ke.yytext=ke.yytext.slice(0,-10).trim(),26;case 39:return 44;case 40:return 45;case 41:return 46;case 42:return 47;case 43:this.pushState("STATE_STRING");break;case 44:return this.pushState("STATE_ID"),"AS";case 45:return this.popState(),"ID";case 46:this.popState();break;case 47:return"STATE_DESCR";case 48:return 18;case 49:this.popState();break;case 50:return this.popState(),this.pushState("struct"),19;case 51:break;case 52:return this.popState(),20;case 53:break;case 54:return this.begin("NOTE"),28;case 55:return this.popState(),this.pushState("NOTE_ID"),52;case 56:return this.popState(),this.pushState("NOTE_ID"),53;case 57:this.popState(),this.pushState("FLOATING_NOTE");break;case 58:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 59:break;case 60:return"NOTE_TEXT";case 61:return this.popState(),"ID";case 62:return this.popState(),this.pushState("NOTE_TEXT"),23;case 63:return this.popState(),ke.yytext=ke.yytext.substr(2).trim(),30;case 64:return this.popState(),ke.yytext=ke.yytext.slice(0,-8).trim(),30;case 65:return 6;case 66:return 6;case 67:return 15;case 68:return 50;case 69:return 23;case 70:return ke.yytext=ke.yytext.trim(),13;case 71:return 14;case 72:return 27;case 73:return 51;case 74:return 5;case 75:return"INVALID"}},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,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/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,32,39,40,41,42,51,52,53,54,68,69,70,71,72],inclusive:!1},FLOATING_NOTE_ID:{rules:[61],inclusive:!1},FLOATING_NOTE:{rules:[58,59,60],inclusive:!1},NOTE_TEXT:{rules:[63,64],inclusive:!1},NOTE_ID:{rules:[62],inclusive:!1},NOTE:{rules:[55,56,57],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,30,31],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[45],inclusive:!1},STATE_STRING:{rules:[46,47],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[9,10,33,34,35,36,37,38,43,44,48,49,50],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,50,54,65,66,67,68,69,70,71,73,74,75],inclusive:!0}}};return Ie}();Fe.lexer=Pe;function je(){this.yy={}}return je.prototype=Fe,Fe.Parser=je,new je}();Nve.parser=Nve;const oKe=Nve,Zin="LR",esn="TB",EJ="state",Pve="relation",tsn="classDef",nsn="applyClass",XR="default",cKe="divider",Bve="[*]",uKe="start",lKe=Bve,hKe="end",fKe="color",dKe="fill",rsn="bgFill",isn=",";function gKe(){return{}}let pKe=Zin,TJ=[],QR=gKe();const bKe=()=>({relations:[],states:{},documents:{}});let CJ={root:bKe()},jg=CJ.root,JR=0,mKe=0;const ssn={LINE:0,DOTTED_LINE:1},asn={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},SJ=i=>JSON.parse(JSON.stringify(i)),osn=i=>{Xe.info("Setting root doc",i),TJ=i},csn=()=>TJ,_J=(i,s,u)=>{if(s.stmt===Pve)_J(i,s.state1,!0),_J(i,s.state2,!1);else if(s.stmt===EJ&&(s.id==="[*]"?(s.id=u?i.id+"_start":i.id+"_end",s.start=u):s.id=s.id.trim()),s.doc){const d=[];let p=[],v;for(v=0;v0&&p.length>0){const b={stmt:EJ,id:bje(),type:"divider",doc:SJ(p)};d.push(SJ(b)),s.doc=d}s.doc.forEach(b=>_J(s,b,!0))}},usn=()=>(_J({id:"root"},{id:"root",doc:TJ},!0),{id:"root",doc:TJ}),lsn=i=>{let s;i.doc?s=i.doc:s=i,Xe.info(s),vKe(!0),Xe.info("Extract",s),s.forEach(u=>{switch(u.stmt){case EJ:rS(u.id.trim(),u.type,u.doc,u.description,u.note,u.classes,u.styles,u.textStyles);break;case Pve:wKe(u.state1,u.state2,u.description);break;case tsn:yKe(u.id.trim(),u.classes);break;case nsn:$ve(u.id.trim(),u.styleClass);break}})},rS=function(i,s=XR,u=null,d=null,p=null,v=null,b=null,y=null){const T=i==null?void 0:i.trim();jg.states[T]===void 0?(Xe.info("Adding state ",T,d),jg.states[T]={id:T,descriptions:[],type:s,doc:u,note:p,classes:[],styles:[],textStyles:[]}):(jg.states[T].doc||(jg.states[T].doc=u),jg.states[T].type||(jg.states[T].type=s)),d&&(Xe.info("Setting state description",T,d),typeof d=="string"&&jve(T,d.trim()),typeof d=="object"&&d.forEach(_=>jve(T,_.trim()))),p&&(jg.states[T].note=p,jg.states[T].note.text=ci.sanitizeText(jg.states[T].note.text,qt())),v&&(Xe.info("Setting state classes",T,v),(typeof v=="string"?[v]:v).forEach(A=>$ve(T,A.trim()))),b&&(Xe.info("Setting state styles",T,b),(typeof b=="string"?[b]:b).forEach(A=>ysn(T,A.trim()))),y&&(Xe.info("Setting state styles",T,b),(typeof y=="string"?[y]:y).forEach(A=>xsn(T,A.trim())))},vKe=function(i){CJ={root:bKe()},jg=CJ.root,JR=0,QR=gKe(),i||Pg()},ZR=function(i){return jg.states[i]},hsn=function(){return jg.states},fsn=function(){Xe.info("Documents = ",CJ)},dsn=function(){return jg.relations};function Fve(i=""){let s=i;return i===Bve&&(JR++,s=`${uKe}${JR}`),s}function Rve(i="",s=XR){return i===Bve?uKe:s}function gsn(i=""){let s=i;return i===lKe&&(JR++,s=`${hKe}${JR}`),s}function psn(i="",s=XR){return i===lKe?hKe:s}function bsn(i,s,u){let d=Fve(i.id.trim()),p=Rve(i.id.trim(),i.type),v=Fve(s.id.trim()),b=Rve(s.id.trim(),s.type);rS(d,p,i.doc,i.description,i.note,i.classes,i.styles,i.textStyles),rS(v,b,s.doc,s.description,s.note,s.classes,s.styles,s.textStyles),jg.relations.push({id1:d,id2:v,relationTitle:ci.sanitizeText(u,qt())})}const wKe=function(i,s,u){if(typeof i=="object")bsn(i,s,u);else{const d=Fve(i.trim()),p=Rve(i),v=gsn(s.trim()),b=psn(s);rS(d,p),rS(v,b),jg.relations.push({id1:d,id2:v,title:ci.sanitizeText(u,qt())})}},jve=function(i,s){const u=jg.states[i],d=s.startsWith(":")?s.replace(":","").trim():s;u.descriptions.push(ci.sanitizeText(d,qt()))},msn=function(i){return i.substring(0,1)===":"?i.substr(2).trim():i.trim()},vsn=()=>(mKe++,"divider-id-"+mKe),yKe=function(i,s=""){QR[i]===void 0&&(QR[i]={id:i,styles:[],textStyles:[]});const u=QR[i];s!=null&&s.split(isn).forEach(d=>{const p=d.replace(/([^;]*);/,"$1").trim();if(d.match(fKe)){const b=p.replace(dKe,rsn).replace(fKe,dKe);u.textStyles.push(b)}u.styles.push(p)})},wsn=function(){return QR},$ve=function(i,s){i.split(",").forEach(function(u){let d=ZR(u);if(d===void 0){const p=u.trim();rS(p),d=ZR(p)}d.classes.push(s)})},ysn=function(i,s){const u=ZR(i);u!==void 0&&u.textStyles.push(s)},xsn=function(i,s){const u=ZR(i);u!==void 0&&u.textStyles.push(s)},G7={getConfig:()=>qt().state,addState:rS,clear:vKe,getState:ZR,getStates:hsn,getRelations:dsn,getClasses:wsn,getDirection:()=>pKe,addRelation:wKe,getDividerId:vsn,setDirection:i=>{pKe=i},cleanupLabel:msn,lineType:ssn,relationType:asn,logDocuments:fsn,getRootDoc:csn,setRootDoc:osn,getRootDocV2:usn,extract:lsn,trimColon:i=>i&&i[0]===":"?i.substr(1).trim():i.trim(),getAccTitle:Cp,setAccTitle:Bg,getAccDescription:_p,setAccDescription:Sp,addStyleClass:yKe,setCssClass:$ve,addDescription:jve,setDiagramTitle:cm,getDiagramTitle:Ap},xKe=i=>` +defs #statediagram-barbEnd { + fill: ${i.transitionColor}; + stroke: ${i.transitionColor}; + } +g.stateGroup text { + fill: ${i.nodeBorder}; + stroke: none; + font-size: 10px; +} +g.stateGroup text { + fill: ${i.textColor}; + stroke: none; + font-size: 10px; + +} +g.stateGroup .state-title { + font-weight: bolder; + fill: ${i.stateLabelColor}; +} + +g.stateGroup rect { + fill: ${i.mainBkg}; + stroke: ${i.nodeBorder}; +} + +g.stateGroup line { + stroke: ${i.lineColor}; + stroke-width: 1; +} + +.transition { + stroke: ${i.transitionColor}; + stroke-width: 1; + fill: none; +} + +.stateGroup .composit { + fill: ${i.background}; + border-bottom: 1px +} + +.stateGroup .alt-composit { + fill: #e0e0e0; + border-bottom: 1px +} + +.state-note { + stroke: ${i.noteBorderColor}; + fill: ${i.noteBkgColor}; + + text { + fill: ${i.noteTextColor}; + stroke: none; + font-size: 10px; + } +} + +.stateLabel .box { + stroke: none; + stroke-width: 0; + fill: ${i.mainBkg}; + opacity: 0.5; +} + +.edgeLabel .label rect { + fill: ${i.labelBackgroundColor}; + opacity: 0.5; +} +.edgeLabel .label text { + fill: ${i.transitionLabelColor||i.tertiaryTextColor}; +} +.label div .edgeLabel { + color: ${i.transitionLabelColor||i.tertiaryTextColor}; +} + +.stateLabel text { + fill: ${i.stateLabelColor}; + font-size: 10px; + font-weight: bold; +} + +.node circle.state-start { + fill: ${i.specialStateColor}; + stroke: ${i.specialStateColor}; +} + +.node .fork-join { + fill: ${i.specialStateColor}; + stroke: ${i.specialStateColor}; +} + +.node circle.state-end { + fill: ${i.innerEndBackground}; + stroke: ${i.background}; + stroke-width: 1.5 +} +.end-state-inner { + fill: ${i.compositeBackground||i.background}; + // stroke: ${i.background}; + stroke-width: 1.5 +} + +.node rect { + fill: ${i.stateBkg||i.mainBkg}; + stroke: ${i.stateBorder||i.nodeBorder}; + stroke-width: 1px; +} +.node polygon { + fill: ${i.mainBkg}; + stroke: ${i.stateBorder||i.nodeBorder};; + stroke-width: 1px; +} +#statediagram-barbEnd { + fill: ${i.lineColor}; +} + +.statediagram-cluster rect { + fill: ${i.compositeTitleBackground}; + stroke: ${i.stateBorder||i.nodeBorder}; + stroke-width: 1px; +} + +.cluster-label, .nodeLabel { + color: ${i.stateLabelColor}; +} + +.statediagram-cluster rect.outer { + rx: 5px; + ry: 5px; +} +.statediagram-state .divider { + stroke: ${i.stateBorder||i.nodeBorder}; +} + +.statediagram-state .title-state { + rx: 5px; + ry: 5px; +} +.statediagram-cluster.statediagram-cluster .inner { + fill: ${i.compositeBackground||i.background}; +} +.statediagram-cluster.statediagram-cluster-alt .inner { + fill: ${i.altBackground?i.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: ${i.altBackground?i.altBackground:"#efefef"}; +} + +.note-edge { + stroke-dasharray: 5; +} + +.statediagram-note rect { + fill: ${i.noteBkgColor}; + stroke: ${i.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} +.statediagram-note rect { + fill: ${i.noteBkgColor}; + stroke: ${i.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} + +.statediagram-note text { + fill: ${i.noteTextColor}; +} + +.statediagram-note .nodeLabel { + color: ${i.noteTextColor}; +} +.statediagram .edgeLabel { + color: red; // ${i.noteTextColor}; +} + +#dependencyStart, #dependencyEnd { + fill: ${i.lineColor}; + stroke: ${i.lineColor}; + stroke-width: 1; +} + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.textColor}; +} +`,zve={},ksn=(i,s)=>{zve[i]=s},Esn=i=>zve[i],kKe=()=>Object.keys(zve),Tsn={get:Esn,set:ksn,keys:kKe,size:()=>kKe().length},Csn=i=>i.append("circle").attr("class","start-state").attr("r",qt().state.sizeUnit).attr("cx",qt().state.padding+qt().state.sizeUnit).attr("cy",qt().state.padding+qt().state.sizeUnit),Ssn=i=>i.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",qt().state.textHeight).attr("class","divider").attr("x2",qt().state.textHeight*2).attr("y1",0).attr("y2",0),_sn=(i,s)=>{const u=i.append("text").attr("x",2*qt().state.padding).attr("y",qt().state.textHeight+2*qt().state.padding).attr("font-size",qt().state.fontSize).attr("class","state-title").text(s.id),d=u.node().getBBox();return i.insert("rect",":first-child").attr("x",qt().state.padding).attr("y",qt().state.padding).attr("width",d.width+2*qt().state.padding).attr("height",d.height+2*qt().state.padding).attr("rx",qt().state.radius),u},Asn=(i,s)=>{const u=function(R,F,j){const K=R.append("tspan").attr("x",2*qt().state.padding).text(F);j||K.attr("dy",qt().state.textHeight)},p=i.append("text").attr("x",2*qt().state.padding).attr("y",qt().state.textHeight+1.3*qt().state.padding).attr("font-size",qt().state.fontSize).attr("class","state-title").text(s.descriptions[0]).node().getBBox(),v=p.height,b=i.append("text").attr("x",qt().state.padding).attr("y",v+qt().state.padding*.4+qt().state.dividerMargin+qt().state.textHeight).attr("class","state-description");let y=!0,T=!0;s.descriptions.forEach(function(R){y||(u(b,R,T),T=!1),y=!1});const _=i.append("line").attr("x1",qt().state.padding).attr("y1",qt().state.padding+v+qt().state.dividerMargin/2).attr("y2",qt().state.padding+v+qt().state.dividerMargin/2).attr("class","descr-divider"),A=b.node().getBBox(),P=Math.max(A.width,p.width);return _.attr("x2",P+3*qt().state.padding),i.insert("rect",":first-child").attr("x",qt().state.padding).attr("y",qt().state.padding).attr("width",P+2*qt().state.padding).attr("height",A.height+v+2*qt().state.padding).attr("rx",qt().state.radius),i},Lsn=(i,s,u)=>{const d=qt().state.padding,p=2*qt().state.padding,v=i.node().getBBox(),b=v.width,y=v.x,T=i.append("text").attr("x",0).attr("y",qt().state.titleShift).attr("font-size",qt().state.fontSize).attr("class","state-title").text(s.id),A=T.node().getBBox().width+p;let P=Math.max(A,b);P===b&&(P=P+p);let R;const F=i.node().getBBox();s.doc,R=y-d,A>b&&(R=(b-P)/2+d),Math.abs(y-F.x)b&&(R=y-(A-b)/2);const j=1-qt().state.textHeight;return i.insert("rect",":first-child").attr("x",R).attr("y",j).attr("class",u?"alt-composit":"composit").attr("width",P).attr("height",F.height+qt().state.textHeight+qt().state.titleShift+1).attr("rx","0"),T.attr("x",R+d),A<=b&&T.attr("x",y+(P-p)/2-A/2+d),i.insert("rect",":first-child").attr("x",R).attr("y",qt().state.titleShift-qt().state.textHeight-qt().state.padding).attr("width",P).attr("height",qt().state.textHeight*3).attr("rx",qt().state.radius),i.insert("rect",":first-child").attr("x",R).attr("y",qt().state.titleShift-qt().state.textHeight-qt().state.padding).attr("width",P).attr("height",F.height+3+2*qt().state.textHeight).attr("rx",qt().state.radius),i},Msn=i=>(i.append("circle").attr("class","end-state-outer").attr("r",qt().state.sizeUnit+qt().state.miniPadding).attr("cx",qt().state.padding+qt().state.sizeUnit+qt().state.miniPadding).attr("cy",qt().state.padding+qt().state.sizeUnit+qt().state.miniPadding),i.append("circle").attr("class","end-state-inner").attr("r",qt().state.sizeUnit).attr("cx",qt().state.padding+qt().state.sizeUnit+2).attr("cy",qt().state.padding+qt().state.sizeUnit+2)),Dsn=(i,s)=>{let u=qt().state.forkWidth,d=qt().state.forkHeight;if(s.parentId){let p=u;u=d,d=p}return i.append("rect").style("stroke","black").style("fill","black").attr("width",u).attr("height",d).attr("x",qt().state.padding).attr("y",qt().state.padding)},Isn=(i,s,u,d)=>{let p=0;const v=d.append("text");v.style("text-anchor","start"),v.attr("class","noteText");let b=i.replace(/\r\n/g,"
");b=b.replace(/\n/g,"
");const y=b.split(ci.lineBreakRegex);let T=1.25*qt().state.noteMargin;for(const _ of y){const A=_.trim();if(A.length>0){const P=v.append("tspan");if(P.text(A),T===0){const R=P.node().getBBox();T+=R.height}p+=T,P.attr("x",s+qt().state.noteMargin),P.attr("y",u+p+1.25*qt().state.noteMargin)}}return{textWidth:v.node().getBBox().width,textHeight:p}},Osn=(i,s)=>{s.attr("class","state-note");const u=s.append("rect").attr("x",0).attr("y",qt().state.padding),d=s.append("g"),{textWidth:p,textHeight:v}=Isn(i,0,0,d);return u.attr("height",v+2*qt().state.noteMargin),u.attr("width",p+qt().state.noteMargin*2),u},EKe=function(i,s){const u=s.id,d={id:u,label:s.id,width:0,height:0},p=i.append("g").attr("id",u).attr("class","stateGroup");s.type==="start"&&Csn(p),s.type==="end"&&Msn(p),(s.type==="fork"||s.type==="join")&&Dsn(p,s),s.type==="note"&&Osn(s.note.text,p),s.type==="divider"&&Ssn(p),s.type==="default"&&s.descriptions.length===0&&_sn(p,s),s.type==="default"&&s.descriptions.length>0&&Asn(p,s);const v=p.node().getBBox();return d.width=v.width+2*qt().state.padding,d.height=v.height+2*qt().state.padding,Tsn.set(u,d),d};let TKe=0;const Nsn=function(i,s,u){const d=function(T){switch(T){case G7.relationType.AGGREGATION:return"aggregation";case G7.relationType.EXTENSION:return"extension";case G7.relationType.COMPOSITION:return"composition";case G7.relationType.DEPENDENCY:return"dependency"}};s.points=s.points.filter(T=>!Number.isNaN(T.y));const p=s.points,v=k7().x(function(T){return T.x}).y(function(T){return T.y}).curve(FF),b=i.append("path").attr("d",v(p)).attr("id","edge"+TKe).attr("class","transition");let y="";if(qt().state.arrowMarkerAbsolute&&(y=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,y=y.replace(/\(/g,"\\("),y=y.replace(/\)/g,"\\)")),b.attr("marker-end","url("+y+"#"+d(G7.relationType.DEPENDENCY)+"End)"),u.title!==void 0){const T=i.append("g").attr("class","stateLabel"),{x:_,y:A}=Ao.calcLabelPosition(s.points),P=ci.getRows(u.title);let R=0;const F=[];let j=0,K=0;for(let oe=0;oe<=P.length;oe++){const pe=T.append("text").attr("text-anchor","middle").text(P[oe]).attr("x",_).attr("y",A+R),be=pe.node().getBBox();j=Math.max(j,be.width),K=Math.min(K,be.x),Xe.info(be.x,_,A+R),R===0&&(R=pe.node().getBBox().height,Xe.info("Title height",R,A)),F.push(pe)}let ee=R*P.length;if(P.length>1){const oe=(P.length-1)*R*.5;F.forEach((pe,be)=>pe.attr("y",A+be*R-oe)),ee=R*P.length}const ie=T.node().getBBox();T.insert("rect",":first-child").attr("class","box").attr("x",_-j/2-qt().state.padding/2).attr("y",A-ee/2-qt().state.padding/2-3.5).attr("width",j+qt().state.padding).attr("height",ee+qt().state.padding),Xe.info(ie)}TKe++};let gm;const qve={},Psn=function(){},Bsn=function(i){i.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")},Fsn=function(i,s,u,d){gm=qt().state;const p=qt().securityLevel;let v;p==="sandbox"&&(v=Ir("#i"+s));const b=Ir(p==="sandbox"?v.nodes()[0].contentDocument.body:"body"),y=p==="sandbox"?v.nodes()[0].contentDocument:document;Xe.debug("Rendering diagram "+i);const T=b.select(`[id='${s}']`);Bsn(T);const _=d.db.getRootDoc();CKe(_,T,void 0,!1,b,y,d);const A=gm.padding,P=T.node().getBBox(),R=P.width+A*2,F=P.height+A*2,j=R*1.75;Ng(T,F,j,gm.useMaxWidth),T.attr("viewBox",`${P.x-gm.padding} ${P.y-gm.padding} `+R+" "+F)},Rsn=i=>i?i.length*gm.fontSizeFactor:1,CKe=(i,s,u,d,p,v,b)=>{const y=new B0({compound:!0,multigraph:!0});let T,_=!0;for(T=0;T{const be=pe.parentElement;let ae=0,ne=0;be&&(be.parentElement&&(ae=be.parentElement.getBBox().width),ne=parseInt(be.getAttribute("data-x-shift"),10),Number.isNaN(ne)&&(ne=0)),pe.setAttribute("x1",0-ne+8),pe.setAttribute("x2",ae-ne-8)})):Xe.debug("No Node "+ie+": "+JSON.stringify(y.node(ie)))});let K=j.getBBox();y.edges().forEach(function(ie){ie!==void 0&&y.edge(ie)!==void 0&&(Xe.debug("Edge "+ie.v+" -> "+ie.w+": "+JSON.stringify(y.edge(ie))),Nsn(s,y.edge(ie),y.edge(ie).relation))}),K=j.getBBox();const ee={id:u||"root",label:u||"root",width:0,height:0};return ee.width=K.width+2*gm.padding,ee.height=K.height+2*gm.padding,Xe.debug("Doc rendered",ee,y),ee},jsn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:oKe,db:G7,renderer:{setConf:Psn,draw:Fsn},styles:xKe,init:i=>{i.state||(i.state={}),i.state.arrowMarkerAbsolute=i.arrowMarkerAbsolute,G7.clear()}}},Symbol.toStringTag,{value:"Module"})),AJ="rect",Hve="rectWithTitle",$sn="start",zsn="end",qsn="divider",Hsn="roundedWithTitle",Vsn="note",Usn="noteGroup",QD="statediagram",Gsn=`${QD}-state`,SKe="transition",Ksn="note",Wsn=`${SKe} note-edge`,Ysn=`${QD}-${Ksn}`,Xsn=`${QD}-cluster`,Qsn=`${QD}-cluster-alt`,_Ke="parent",AKe="note",Jsn="state",Vve="----",Zsn=`${Vve}${AKe}`,LKe=`${Vve}${_Ke}`,MKe="fill:none",DKe="fill: #333",IKe="c",OKe="text",NKe="normal";let LJ={},j9=0;const ean=function(i){const s=Object.keys(i);for(const u of s)i[u]},tan=function(i,s){return s.db.extract(s.db.getRootDocV2()),s.db.getClasses()};function nan(i){return i==null?"":i.classes?i.classes.join(" "):""}function Uve(i="",s=0,u="",d=Vve){const p=u!==null&&u.length>0?`${d}${u}`:"";return`${Jsn}-${i}${p}-${s}`}const ej=(i,s,u,d,p,v)=>{const b=u.id,y=nan(d[b]);if(b!=="root"){let T=AJ;u.start===!0&&(T=$sn),u.start===!1&&(T=zsn),u.type!==XR&&(T=u.type),LJ[b]||(LJ[b]={id:b,shape:T,description:ci.sanitizeText(b,qt()),classes:`${y} ${Gsn}`});const _=LJ[b];u.description&&(Array.isArray(_.description)?(_.shape=Hve,_.description.push(u.description)):_.description.length>0?(_.shape=Hve,_.description===b?_.description=[u.description]:_.description=[_.description,u.description]):(_.shape=AJ,_.description=u.description),_.description=ci.sanitizeTextOrArray(_.description,qt())),_.description.length===1&&_.shape===Hve&&(_.shape=AJ),!_.type&&u.doc&&(Xe.info("Setting cluster for ",b,Gve(u)),_.type="group",_.dir=Gve(u),_.shape=u.type===cKe?qsn:Hsn,_.classes=_.classes+" "+Xsn+" "+(v?Qsn:""));const A={labelStyle:"",shape:_.shape,labelText:_.description,classes:_.classes,style:"",id:b,dir:_.dir,domId:Uve(b,j9),type:_.type,padding:15};if(A.centerLabel=!0,u.note){const P={labelStyle:"",shape:Vsn,labelText:u.note.text,classes:Ysn,style:"",id:b+Zsn+"-"+j9,domId:Uve(b,j9,AKe),type:_.type,padding:15},R={labelStyle:"",shape:Usn,labelText:u.note.text,classes:_.classes,style:"",id:b+LKe,domId:Uve(b,j9,_Ke),type:"group",padding:0};j9++;const F=b+LKe;i.setNode(F,R),i.setNode(P.id,P),i.setNode(b,A),i.setParent(b,F),i.setParent(P.id,F);let j=b,K=P.id;u.note.position==="left of"&&(j=P.id,K=b),i.setEdge(j,K,{arrowhead:"none",arrowType:"",style:MKe,labelStyle:"",classes:Wsn,arrowheadStyle:DKe,labelpos:IKe,labelType:OKe,thickness:NKe})}else i.setNode(b,A)}s&&s.id!=="root"&&(Xe.trace("Setting node ",b," to be child of its parent ",s.id),i.setParent(b,s.id)),u.doc&&(Xe.trace("Adding nodes children "),ran(i,u,u.doc,d,p,!v))},ran=(i,s,u,d,p,v)=>{Xe.trace("items",u),u.forEach(b=>{switch(b.stmt){case EJ:ej(i,s,b,d,p,v);break;case XR:ej(i,s,b,d,p,v);break;case Pve:{ej(i,s,b.state1,d,p,v),ej(i,s,b.state2,d,p,v);const y={id:"edge"+j9,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:MKe,labelStyle:"",label:ci.sanitizeText(b.description,qt()),arrowheadStyle:DKe,labelpos:IKe,labelType:OKe,thickness:NKe,classes:SKe};i.setEdge(b.state1.id,b.state2.id,y,j9),j9++}break}})},Gve=(i,s=esn)=>{let u=s;if(i.doc)for(let d=0;d{i.state||(i.state={}),i.state.arrowMarkerAbsolute=i.arrowMarkerAbsolute,G7.clear()}}},Symbol.toStringTag,{value:"Module"}));var Kve=function(){var i=function(P,R,F,j){for(F=F||{},j=P.length;j--;F[P[j]]=R);return F},s=[6,8,10,11,12,14,16,17,18],u=[1,9],d=[1,10],p=[1,11],v=[1,12],b=[1,13],y=[1,14],T={trace:function(){},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:function(R,F,j,K,ee,ie,oe){var pe=ie.length-1;switch(ee){case 1:return ie[pe-1];case 2:this.$=[];break;case 3:ie[pe-1].push(ie[pe]),this.$=ie[pe-1];break;case 4:case 5:this.$=ie[pe];break;case 6:case 7:this.$=[];break;case 8:K.setDiagramTitle(ie[pe].substr(6)),this.$=ie[pe].substr(6);break;case 9:this.$=ie[pe].trim(),K.setAccTitle(this.$);break;case 10:case 11:this.$=ie[pe].trim(),K.setAccDescription(this.$);break;case 12:K.addSection(ie[pe].substr(8)),this.$=ie[pe].substr(8);break;case 13:K.addTask(ie[pe-1],ie[pe]),this.$="task";break}},table:[{3:1,4:[1,2]},{1:[3]},i(s,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:u,12:d,14:p,16:v,17:b,18:y},i(s,[2,7],{1:[2,1]}),i(s,[2,3]),{9:15,11:u,12:d,14:p,16:v,17:b,18:y},i(s,[2,5]),i(s,[2,6]),i(s,[2,8]),{13:[1,16]},{15:[1,17]},i(s,[2,11]),i(s,[2,12]),{19:[1,18]},i(s,[2,4]),i(s,[2,9]),i(s,[2,10]),i(s,[2,13])],defaultActions:{},parseError:function(R,F){if(F.recoverable)this.trace(R);else{var j=new Error(R);throw j.hash=F,j}},parse:function(R){var F=this,j=[0],K=[],ee=[null],ie=[],oe=this.table,pe="",be=0,ae=0,ne=2,se=1,de=ie.slice.call(arguments,1),X=Object.create(this.lexer),ge={yy:{}};for(var W in this.yy)Object.prototype.hasOwnProperty.call(this.yy,W)&&(ge.yy[W]=this.yy[W]);X.setInput(R,ge.yy),ge.yy.lexer=X,ge.yy.parser=this,typeof X.yylloc>"u"&&(X.yylloc={});var xe=X.yylloc;ie.push(xe);var U=X.options&&X.options.ranges;typeof ge.yy.parseError=="function"?this.parseError=ge.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Fe(){var _t;return _t=K.pop()||X.lex()||se,typeof _t!="number"&&(_t instanceof Array&&(K=_t,_t=K.pop()),_t=F.symbols_[_t]||_t),_t}for(var Pe,je,Ie,Se,Ce={},ke,Ke,Ft,Ne;;){if(je=j[j.length-1],this.defaultActions[je]?Ie=this.defaultActions[je]:((Pe===null||typeof Pe>"u")&&(Pe=Fe()),Ie=oe[je]&&oe[je][Pe]),typeof Ie>"u"||!Ie.length||!Ie[0]){var gn="";Ne=[];for(ke in oe[je])this.terminals_[ke]&&ke>ne&&Ne.push("'"+this.terminals_[ke]+"'");X.showPosition?gn="Parse error on line "+(be+1)+`: +`+X.showPosition()+` +Expecting `+Ne.join(", ")+", got '"+(this.terminals_[Pe]||Pe)+"'":gn="Parse error on line "+(be+1)+": Unexpected "+(Pe==se?"end of input":"'"+(this.terminals_[Pe]||Pe)+"'"),this.parseError(gn,{text:X.match,token:this.terminals_[Pe]||Pe,line:X.yylineno,loc:xe,expected:Ne})}if(Ie[0]instanceof Array&&Ie.length>1)throw new Error("Parse Error: multiple actions possible at state: "+je+", token: "+Pe);switch(Ie[0]){case 1:j.push(Pe),ee.push(X.yytext),ie.push(X.yylloc),j.push(Ie[1]),Pe=null,ae=X.yyleng,pe=X.yytext,be=X.yylineno,xe=X.yylloc;break;case 2:if(Ke=this.productions_[Ie[1]][1],Ce.$=ee[ee.length-Ke],Ce._$={first_line:ie[ie.length-(Ke||1)].first_line,last_line:ie[ie.length-1].last_line,first_column:ie[ie.length-(Ke||1)].first_column,last_column:ie[ie.length-1].last_column},U&&(Ce._$.range=[ie[ie.length-(Ke||1)].range[0],ie[ie.length-1].range[1]]),Se=this.performAction.apply(Ce,[pe,ae,be,ge.yy,Ie[1],ee,ie].concat(de)),typeof Se<"u")return Se;Ke&&(j=j.slice(0,-1*Ke*2),ee=ee.slice(0,-1*Ke),ie=ie.slice(0,-1*Ke)),j.push(this.productions_[Ie[1]][0]),ee.push(Ce.$),ie.push(Ce._$),Ft=oe[j[j.length-2]][j[j.length-1]],j.push(Ft);break;case 3:return!0}}return!0}},_=function(){var P={EOF:1,parseError:function(F,j){if(this.yy.parser)this.yy.parser.parseError(F,j);else throw new Error(F)},setInput:function(R,F){return this.yy=F||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},input:function(){var R=this._input[0];this.yytext+=R,this.yyleng++,this.offset++,this.match+=R,this.matched+=R;var F=R.match(/(?:\r\n?|\n).*/g);return F?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),R},unput:function(R){var F=R.length,j=R.split(/(?:\r\n?|\n)/g);this._input=R+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-F),this.offset-=F;var K=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 ee=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===K.length?this.yylloc.first_column:0)+K[K.length-j.length].length-j[0].length:this.yylloc.first_column-F},this.options.ranges&&(this.yylloc.range=[ee[0],ee[0]+this.yyleng-F]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(R){this.unput(this.match.slice(R))},pastInput:function(){var R=this.matched.substr(0,this.matched.length-this.match.length);return(R.length>20?"...":"")+R.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var R=this.pastInput(),F=new Array(R.length+1).join("-");return R+this.upcomingInput()+` +`+F+"^"},test_match:function(R,F){var j,K,ee;if(this.options.backtrack_lexer&&(ee={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&&(ee.yylloc.range=this.yylloc.range.slice(0))),K=R[0].match(/(?:\r\n?|\n).*/g),K&&(this.yylineno+=K.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:K?K[K.length-1].length-K[K.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],j=this.performAction.call(this,this.yy,this,F,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),j)return j;if(this._backtrack){for(var ie in ee)this[ie]=ee[ie];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var R,F,j,K;this._more||(this.yytext="",this.match="");for(var ee=this._currentRules(),ie=0;ieF[0].length)){if(F=j,K=ie,this.options.backtrack_lexer){if(R=this.test_match(j,ee[ie]),R!==!1)return R;if(this._backtrack){F=!1;continue}else return!1}else if(!this.options.flex)break}return F?(R=this.test_match(F,ee[K]),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})},lex:function(){var F=this.next();return F||this.lex()},begin:function(F){this.conditionStack.push(F)},popState:function(){var F=this.conditionStack.length-1;return F>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(F){return F=this.conditionStack.length-1-Math.abs(F||0),F>=0?this.conditionStack[F]:"INITIAL"},pushState:function(F){this.begin(F)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(F,j,K,ee){switch(K){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;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";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"}},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 P}();T.lexer=_;function A(){this.yy={}}return A.prototype=T,T.Parser=A,new A}();Kve.parser=Kve;const san=Kve;let JD="";const Wve=[],tj=[],nj=[],aan=function(){Wve.length=0,tj.length=0,JD="",nj.length=0,Pg()},oan=function(i){JD=i,Wve.push(i)},can=function(){return Wve},uan=function(){let i=PKe();const s=100;let u=0;for(;!i&&u{u.people&&i.push(...u.people)}),[...new Set(i)].sort()},han=function(i,s){const u=s.substr(1).split(":");let d=0,p=[];u.length===1?(d=Number(u[0]),p=[]):(d=Number(u[0]),p=u[1].split(","));const v=p.map(y=>y.trim()),b={section:JD,type:JD,people:v,task:i,score:d};nj.push(b)},fan=function(i){const s={section:JD,type:JD,description:i,task:i,classes:[]};tj.push(s)},PKe=function(){const i=function(u){return nj[u].processed};let s=!0;for(const[u,d]of nj.entries())i(u),s=s&&d.processed;return s},BKe={getConfig:()=>qt().journey,clear:aan,setDiagramTitle:cm,getDiagramTitle:Ap,setAccTitle:Bg,getAccTitle:Cp,setAccDescription:Sp,getAccDescription:_p,addSection:oan,getSections:can,getTasks:uan,addTask:han,addTaskOrg:fan,getActors:function(){return lan()}},dan=i=>`.label { + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + color: ${i.textColor}; + } + .mouth { + stroke: #666; + } + + line { + stroke: ${i.textColor} + } + + .legend { + fill: ${i.textColor}; + } + + .label text { + fill: #333; + } + .label { + color: ${i.textColor} + } + + .face { + ${i.faceColor?`fill: ${i.faceColor}`:"fill: #FFF8DC"}; + stroke: #999; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${i.mainBkg}; + stroke: ${i.nodeBorder}; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${i.arrowheadColor}; + } + + .edgePath .path { + stroke: ${i.lineColor}; + stroke-width: 1.5px; + } + + .flowchart-link { + stroke: ${i.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${i.edgeLabelBackground}; + rect { + opacity: 0.5; + } + text-align: center; + } + + .cluster rect { + } + + .cluster text { + fill: ${i.titleColor}; + } + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + font-size: 12px; + background: ${i.tertiaryColor}; + border: 1px solid ${i.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .task-type-0, .section-type-0 { + ${i.fillType0?`fill: ${i.fillType0}`:""}; + } + .task-type-1, .section-type-1 { + ${i.fillType0?`fill: ${i.fillType1}`:""}; + } + .task-type-2, .section-type-2 { + ${i.fillType0?`fill: ${i.fillType2}`:""}; + } + .task-type-3, .section-type-3 { + ${i.fillType0?`fill: ${i.fillType3}`:""}; + } + .task-type-4, .section-type-4 { + ${i.fillType0?`fill: ${i.fillType4}`:""}; + } + .task-type-5, .section-type-5 { + ${i.fillType0?`fill: ${i.fillType5}`:""}; + } + .task-type-6, .section-type-6 { + ${i.fillType0?`fill: ${i.fillType6}`:""}; + } + .task-type-7, .section-type-7 { + ${i.fillType0?`fill: ${i.fillType7}`:""}; + } + + .actor-0 { + ${i.actor0?`fill: ${i.actor0}`:""}; + } + .actor-1 { + ${i.actor1?`fill: ${i.actor1}`:""}; + } + .actor-2 { + ${i.actor2?`fill: ${i.actor2}`:""}; + } + .actor-3 { + ${i.actor3?`fill: ${i.actor3}`:""}; + } + .actor-4 { + ${i.actor4?`fill: ${i.actor4}`:""}; + } + .actor-5 { + ${i.actor5?`fill: ${i.actor5}`:""}; + } +`,Yve=function(i,s){return AQ(i,s)},gan=function(i,s){const d=i.append("circle").attr("cx",s.cx).attr("cy",s.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),p=i.append("g");p.append("circle").attr("cx",s.cx-15/3).attr("cy",s.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),p.append("circle").attr("cx",s.cx+15/3).attr("cy",s.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function v(T){const _=lD().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);T.append("path").attr("class","mouth").attr("d",_).attr("transform","translate("+s.cx+","+(s.cy+2)+")")}function b(T){const _=lD().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);T.append("path").attr("class","mouth").attr("d",_).attr("transform","translate("+s.cx+","+(s.cy+7)+")")}function y(T){T.append("line").attr("class","mouth").attr("stroke",2).attr("x1",s.cx-5).attr("y1",s.cy+7).attr("x2",s.cx+5).attr("y2",s.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return s.score>3?v(p):s.score<3?b(p):y(p),d},FKe=function(i,s){const u=i.append("circle");return u.attr("cx",s.cx),u.attr("cy",s.cy),u.attr("class","actor-"+s.pos),u.attr("fill",s.fill),u.attr("stroke",s.stroke),u.attr("r",s.r),u.class!==void 0&&u.attr("class",u.class),s.title!==void 0&&u.append("title").text(s.title),u},RKe=function(i,s){return tUt(i,s)},pan=function(i,s){function u(p,v,b,y,T){return p+","+v+" "+(p+b)+","+v+" "+(p+b)+","+(v+y-T)+" "+(p+b-T*1.2)+","+(v+y)+" "+p+","+(v+y)}const d=i.append("polygon");d.attr("points",u(s.x,s.y,50,20,7)),d.attr("class","labelBox"),s.y=s.y+s.labelMargin,s.x=s.x+.5*s.labelMargin,RKe(i,s)},ban=function(i,s,u){const d=i.append("g"),p=qC();p.x=s.x,p.y=s.y,p.fill=s.fill,p.width=u.width*s.taskCount+u.diagramMarginX*(s.taskCount-1),p.height=u.height,p.class="journey-section section-type-"+s.num,p.rx=3,p.ry=3,Yve(d,p),$Ke(u)(s.text,d,p.x,p.y,p.width,p.height,{class:"journey-section section-type-"+s.num},u,s.colour)};let jKe=-1;const man=function(i,s,u){const d=s.x+u.width/2,p=i.append("g");jKe++;const v=300+5*30;p.append("line").attr("id","task"+jKe).attr("x1",d).attr("y1",s.y).attr("x2",d).attr("y2",v).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),gan(p,{cx:d,cy:300+(5-s.score)*30,score:s.score});const b=qC();b.x=s.x,b.y=s.y,b.fill=s.fill,b.width=u.width,b.height=u.height,b.class="task task-type-"+s.num,b.rx=3,b.ry=3,Yve(p,b);let y=s.x+14;s.people.forEach(T=>{const _=s.actors[T].color,A={cx:y,cy:s.y,r:7,fill:_,stroke:"#000",title:T,pos:s.actors[T].position};FKe(p,A),y+=10}),$Ke(u)(s.task,p,b.x,b.y,b.width,b.height,{class:"task"},u,s.colour)},van=function(i,s){Tqe(i,s)},$Ke=function(){function i(p,v,b,y,T,_,A,P){const R=v.append("text").attr("x",b+T/2).attr("y",y+_/2+5).style("font-color",P).style("text-anchor","middle").text(p);d(R,A)}function s(p,v,b,y,T,_,A,P,R){const{taskFontSize:F,taskFontFamily:j}=P,K=p.split(//gi);for(let ee=0;ee{const p=K7[d].color,v={cx:20,cy:u,r:7,fill:p,stroke:"#000",pos:K7[d].position};rj.drawCircle(i,v);const b={x:40,y:u+7,fill:"#666",text:d,textMargin:s.boxTextMargin|5};rj.drawText(i,b),u+=20})}const MJ=qt().journey,iS=MJ.leftMargin,xan=function(i,s,u,d){const p=qt().journey,v=qt().securityLevel;let b;v==="sandbox"&&(b=Ir("#i"+s));const y=Ir(v==="sandbox"?b.nodes()[0].contentDocument.body:"body");qv.init();const T=y.select("#"+s);rj.initGraphics(T);const _=d.db.getTasks(),A=d.db.getDiagramTitle(),P=d.db.getActors();for(const ie in K7)delete K7[ie];let R=0;P.forEach(ie=>{K7[ie]={color:p.actorColours[R%p.actorColours.length],position:R},R++}),yan(T),qv.insert(0,0,iS,Object.keys(K7).length*50),kan(T,_,0);const F=qv.getBounds();A&&T.append("text").text(A).attr("x",iS).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const j=F.stopy-F.starty+2*p.diagramMarginY,K=iS+F.stopx+2*p.diagramMarginX;Ng(T,j,K,p.useMaxWidth),T.append("line").attr("x1",iS).attr("y1",p.height*4).attr("x2",K-iS-4).attr("y2",p.height*4).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const ee=A?70:0;T.attr("viewBox",`${F.startx} -25 ${K} ${j+ee}`),T.attr("preserveAspectRatio","xMinYMin meet"),T.attr("height",j+ee+25)},qv={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(i,s,u,d){i[s]===void 0?i[s]=u:i[s]=d(u,i[s])},updateBounds:function(i,s,u,d){const p=qt().journey,v=this;let b=0;function y(T){return function(A){b++;const P=v.sequenceItems.length-b+1;v.updateVal(A,"starty",s-P*p.boxMargin,Math.min),v.updateVal(A,"stopy",d+P*p.boxMargin,Math.max),v.updateVal(qv.data,"startx",i-P*p.boxMargin,Math.min),v.updateVal(qv.data,"stopx",u+P*p.boxMargin,Math.max),T!=="activation"&&(v.updateVal(A,"startx",i-P*p.boxMargin,Math.min),v.updateVal(A,"stopx",u+P*p.boxMargin,Math.max),v.updateVal(qv.data,"starty",s-P*p.boxMargin,Math.min),v.updateVal(qv.data,"stopy",d+P*p.boxMargin,Math.max))}}this.sequenceItems.forEach(y())},insert:function(i,s,u,d){const p=Math.min(i,u),v=Math.max(i,u),b=Math.min(s,d),y=Math.max(s,d);this.updateVal(qv.data,"startx",p,Math.min),this.updateVal(qv.data,"starty",b,Math.min),this.updateVal(qv.data,"stopx",v,Math.max),this.updateVal(qv.data,"stopy",y,Math.max),this.updateBounds(p,b,v,y)},bumpVerticalPos:function(i){this.verticalPos=this.verticalPos+i,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},Xve=MJ.sectionFills,zKe=MJ.sectionColours,kan=function(i,s,u){const d=qt().journey;let p="";const v=d.height*2+d.diagramMarginY,b=u+v;let y=0,T="#CCC",_="black",A=0;for(const[P,R]of s.entries()){if(p!==R.section){T=Xve[y%Xve.length],A=y%Xve.length,_=zKe[y%zKe.length];let j=0;const K=R.section;for(let ie=P;ie(K7[K]&&(j[K]=K7[K]),j),{});R.x=P*d.taskMargin+P*d.width+iS,R.y=b,R.width=d.diagramMarginX,R.height=d.diagramMarginY,R.colour=_,R.fill=T,R.num=A,R.actors=F,rj.drawTask(i,R,d),qv.insert(R.x,R.y,R.x+R.width+d.taskMargin,300+5*30)}},qKe={setConf:wan,draw:xan},Ean=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:san,db:BKe,renderer:qKe,styles:dan,init:i=>{qKe.setConf(i.journey),BKe.clear()}}},Symbol.toStringTag,{value:"Module"})),Tan=(i,s,u)=>{const{parentById:d}=u,p=new Set;let v=i;for(;v;){if(p.add(v),v===s)return v;v=d[v]}for(v=s;v;){if(p.has(v))return v;v=d[v]}return"root"};function DJ(i){throw new Error('Could not dynamically require "'+i+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var HKe={exports:{}};(function(i,s){(function(u){i.exports=u()})(function(){return function(){function u(d,p,v){function b(_,A){if(!p[_]){if(!d[_]){var P=typeof DJ=="function"&&DJ;if(!A&&P)return P(_,!0);if(y)return y(_,!0);var R=new Error("Cannot find module '"+_+"'");throw R.code="MODULE_NOT_FOUND",R}var F=p[_]={exports:{}};d[_][0].call(F.exports,function(j){var K=d[_][1][j];return b(K||j)},F,F.exports,u,d,p,v)}return p[_].exports}for(var y=typeof DJ=="function"&&DJ,T=0;T0&&arguments[0]!==void 0?arguments[0]:{},R=P.defaultLayoutOptions,F=R===void 0?{}:R,j=P.algorithms,K=j===void 0?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:j,ee=P.workerFactory,ie=P.workerUrl;if(b(this,_),this.defaultLayoutOptions=F,this.initialized=!1,typeof ie>"u"&&typeof ee>"u")throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var oe=ee;typeof ie<"u"&&typeof ee>"u"&&(oe=function(ae){return new Worker(ae)});var pe=oe(ie);if(typeof pe.postMessage!="function")throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new T(pe),this.worker.postMessage({cmd:"register",algorithms:K}).then(function(be){return A.initialized=!0}).catch(console.err)}return v(_,[{key:"layout",value:function(P){var R=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},F=R.layoutOptions,j=F===void 0?this.defaultLayoutOptions:F,K=R.logging,ee=K===void 0?!1:K,ie=R.measureExecutionTime,oe=ie===void 0?!1:ie;return P?this.worker.postMessage({cmd:"layout",graph:P,layoutOptions:j,options:{logging:ee,measureExecutionTime:oe}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker.terminate()}}]),_}();p.default=y;var T=function(){function _(A){var P=this;if(b(this,_),A===void 0)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=A,this.worker.onmessage=function(R){setTimeout(function(){P.receive(P,R)},0)}}return v(_,[{key:"postMessage",value:function(P){var R=this.id||0;this.id=R+1,P.id=R;var F=this;return new Promise(function(j,K){F.resolvers[R]=function(ee,ie){ee?(F.convertGwtStyleError(ee),K(ee)):j(ie)},F.worker.postMessage(P)})}},{key:"receive",value:function(P,R){var F=R.data,j=P.resolvers[F.id];j&&(delete P.resolvers[F.id],F.error?j(F.error):j(null,F.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(P){if(P){var R=P.__java$exception;R&&(R.cause&&R.cause.backingJsObject&&(P.cause=R.cause.backingJsObject,this.convertGwtStyleError(P.cause)),delete P.__java$exception)}}}]),_}()},{}],2:[function(u,d,p){(function(v){(function(){var b;typeof window<"u"?b=window:typeof v<"u"?b=v:typeof self<"u"&&(b=self);var y;function T(){}function _(){}function A(){}function P(){}function R(){}function F(){}function j(){}function K(){}function ee(){}function ie(){}function oe(){}function pe(){}function be(){}function ae(){}function ne(){}function se(){}function de(){}function X(){}function ge(){}function W(){}function xe(){}function U(){}function Fe(){}function Pe(){}function je(){}function Ie(){}function Se(){}function Ce(){}function ke(){}function Ke(){}function Ft(){}function Ne(){}function gn(){}function _t(){}function Et(){}function Gt(){}function ln(){}function xt(){}function Pt(){}function Qe(){}function Dt(){}function kt(){}function On(){}function ht(){}function zr(){}function yt(){}function ji(){}function xi(){}function Ma(){}function zs(){}function ao(){}function Tr(){}function Fn(){}function qn(){}function Un(){}function At(){}function wt(){}function on(){}function fn(){}function An(){}function oo(){}function jo(){}function $o(){}function Pa(){}function wo(){}function _s(){}function tl(){}function da(){}function j0(){}function pm(){}function Ml(){}function Xc(){}function Bc(){}function ja(){}function Ou(){}function Sa(){}function Po(){}function Fc(){}function xa(){}function Ba(){}function ga(){}function kh(){}function lu(){}function o5(){}function Wh(){}function od(){}function Gd(){}function cd(){}function Kd(){}function $g(){}function as(){}function wn(){}function Zr(){}function Zi(){}function nu(){}function vu(){}function Dl(){}function Yh(){}function w1(){}function $0(){}function Wi(){}function Bs(){}function Qa(){}function Bi(){}function Nu(){}function Ot(){}function W3(){}function Kt(){}function z0(){}function Bp(){}function Y3(){}function $9(){}function c5(){}function Eh(){}function zg(){}function bm(){}function z9(){}function mm(){}function u5(){}function y1(){}function ud(){}function ld(){}function q9(){}function Vv(){}function Y7(){}function G2(){}function X7(){}function l5(){}function X3(){}function Fp(){}function nI(){}function ch(){}function oS(){}function hu(){}function $J(){}function vm(){}function zJ(){}function oj(){}function qJ(){}function cj(){}function q0(){}function Q3(){}function cS(){}function uj(){}function K2(){}function J3(){}function HJ(){}function wm(){}function VJ(){}function UJ(){}function Q7(){}function uS(){}function lj(){}function H9(){}function GJ(){}function V9(){}function KJ(){}function WJ(){}function YJ(){}function XJ(){}function QJ(){}function JJ(){}function ZJ(){}function eZ(){}function tZ(){}function nZ(){}function rZ(){}function rI(){}function iZ(){}function sZ(){}function lS(){}function hj(){}function J7(){}function aZ(){}function oZ(){}function cZ(){}function uZ(){}function lZ(){}function hS(){}function iI(){}function fj(){}function h5(){}function f5(){}function hZ(){}function t0(){}function Z7(){}function fZ(){}function U9(){}function Wd(){}function dZ(){}function gZ(){}function pZ(){}function dj(){}function bZ(){}function fS(){}function dS(){}function gj(){}function sI(){}function e8(){}function mZ(){}function pj(){}function bj(){}function vZ(){}function wZ(){}function yZ(){}function xZ(){}function kZ(){}function EZ(){}function Yd(){}function Uv(){}function TZ(){}function gS(){}function pS(){}function CZ(){}function d5(){}function G9(){}function aI(){}function Z3(){}function K9(){}function SZ(){}function bS(){}function hd(){}function mj(){}function oI(){}function W9(){}function cI(){}function vj(){}function _Z(){}function uI(){}function AZ(){}function LZ(){}function wj(){}function t8(){}function yj(){}function n8(){}function MZ(){}function lI(){}function DZ(){}function IZ(){}function OZ(){}function NZ(){}function xj(){}function PZ(){}function BZ(){}function kj(){}function FZ(){}function RZ(){}function jZ(){}function $Z(){}function Ej(){}function zZ(){}function qZ(){}function Tj(){}function Cj(){}function Sj(){}function HZ(){}function VZ(){}function Y9(){}function r8(){}function mS(){}function UZ(){}function hI(){}function vS(){}function fI(){}function _j(){}function Aj(){}function GZ(){}function KZ(){}function WZ(){}function Lj(){}function Mj(){}function YZ(){}function XZ(){}function QZ(){}function JZ(){}function ZZ(){}function Dj(){}function eee(){}function tee(){}function nee(){}function ree(){}function Ij(){}function wS(){}function iee(){}function see(){}function Oj(){}function aee(){}function oee(){}function cee(){}function uee(){}function lee(){}function hee(){}function Nj(){}function fee(){}function Pj(){}function dee(){}function gee(){}function pee(){}function yS(){}function bee(){}function xS(){}function mee(){}function Bj(){}function Fj(){}function Rj(){}function jj(){}function Gv(){}function $j(){}function zj(){}function qj(){}function Hj(){}function vee(){}function i8(){}function dI(){}function g5(){}function wee(){}function yee(){}function kS(){}function Vj(){}function xee(){}function kee(){}function Eee(){}function Tee(){}function Cee(){}function See(){}function _ee(){}function Aee(){}function Lee(){}function Mee(){}function ES(){}function Uj(){}function Dee(){}function Iee(){}function Oee(){}function Nee(){}function Pee(){}function Gj(){}function Kj(){}function Bee(){}function Wj(){}function Yj(){}function Fee(){}function Ree(){}function jee(){}function $ee(){}function zee(){}function qee(){}function Hee(){}function Vee(){}function gI(){}function Uee(){}function X9(){}function Xj(){}function Gee(){}function Kee(){}function Wee(){}function Yee(){}function Xee(){}function Qee(){}function Jee(){}function Zee(){}function ete(){}function tte(){}function nte(){}function rte(){}function ite(){}function ste(){}function ate(){}function s8(){}function Qj(){}function ote(){}function cte(){}function ute(){}function Jj(){}function lte(){}function TS(){}function hte(){}function fte(){}function dte(){}function gte(){}function pte(){}function bte(){}function mte(){}function vte(){}function wte(){}function yte(){}function a8(){}function xte(){}function kte(){}function Ete(){}function Tte(){}function Cte(){}function Ste(){}function _te(){}function Ate(){}function CS(){}function Lte(){}function Mte(){}function Dte(){}function Ite(){}function Ote(){}function Nte(){}function Pte(){}function Bte(){}function o8(){}function Zj(){}function Fte(){}function pI(){}function Rte(){}function jte(){}function $te(){}function zte(){}function qte(){}function Hte(){}function Vte(){}function e$(){}function Ute(){}function t$(){}function Gte(){}function n$(){}function r$(){}function i$(){}function Kte(){}function Wte(){}function s$(){}function Yte(){}function a$(){}function Xte(){}function Qte(){}function bI(){}function Jte(){}function Zte(){}function ene(){}function tne(){}function nne(){}function o$(){}function rne(){}function ine(){}function sne(){}function pwe(){}function ane(){}function one(){}function cne(){}function une(){}function lne(){}function hne(){}function fne(){}function dne(){}function gne(){}function pne(){}function bne(){}function mne(){}function vne(){}function wne(){}function yne(){}function xne(){}function fu(){}function kne(){}function SS(){}function Rc(){}function Pu(){}function hs(){}function mI(){}function Ene(){}function Tne(){}function Cne(){}function c8(){}function ym(){}function Q9(){}function Sne(){}function vI(){}function _ne(){}function Ane(){}function Lne(){}function c$(){}function Mne(){}function Dne(){}function wI(){}function Ine(){}function uh(){}function gl(){}function u$(){}function One(){}function Nne(){}function ey(){}function p5(){}function ty(){}function Rp(){}function u8(){}function yI(){}function l$(){}function h$(){}function Pne(){}function x1(){}function f$(){}function ny(){}function J9(){}function xI(){}function l8(){}function W2(){}function d$(){}function g$(){}function p$(){}function Bne(){}function h8(){}function ry(){}function jp(){}function Y2(){}function b5(){}function Z9(){}function _S(){}function kI(){}function Fne(){}function Rne(){}function b$(){}function m$(){}function Ut(){}function ek(){}function v$(){}function w$(){}function jne(){}function tk(){}function nk(){}function y$(){}function $ne(){}function zne(){}function qne(){}function Hne(){}function Vne(){}function Une(){}function EI(){}function Gne(){}function Kne(){}function x$(){}function AS(){}function Wne(){}function TI(){}function rk(){}function ik(){}function sk(){}function k$(){}function Yne(){}function E$(){}function T$(){}function Xne(){}function LS(){}function X2(){}function C$(){}function S$(){}function MS(){}function Qne(){}function m5(){}function _$(){}function CI(){}function Qc(){}function SI(){}function _I(){}function DS(){}function Jne(){}function Zne(){}function IS(){}function ere(){}function OS(){}function NS(){}function H0(){}function AI(){}function LI(){}function f8(){}function tre(){}function nre(){}function rre(){}function ire(){}function Xd(){}function PS(){}function d8(){}function k1(){}function A$(){}function L$(){}function M$(){}function D$(){}function I$(){}function O$(){}function V0(){}function nl(){}function sre(){}function are(){}function ore(){}function rl(){}function BS(){}function N$(){}function P$(){}function g8(){}function cre(){}function ak(){}function ure(){}function B$(){}function lre(){}function hre(){}function FS(){}function F$(){}function MI(){}function RS(){}function fre(){}function dre(){}function DI(){}function jS(){}function E1(){}function ok(){}function gre(){}function ck(){}function II(){}function xm(){}function $S(){}function OI(){}function U0(){}function zS(){}function T1(){}function C1(){}function pre(){}function bre(){}function v5(){}function uk(){}function lk(){}function qS(){}function mre(){}function vre(){}function p8(){}function R$(){}function j$(){}function wre(){}function $$(){}function yre(){}function z$(){}function NI(){}function xre(){}function HS(){}function kre(){}function Ere(){}function Tre(){}function Cre(){}function Sre(){}function q$(){}function _re(){}function Are(){}function Lre(){}function H$(){}function Mre(){}function Dre(){}function VS(){}function Ire(){}function Ore(){}function Nre(){}function Pre(){}function Bre(){}function Fre(){}function V$(){}function Rre(){}function U$(){}function jre(){}function PI(){}function $re(){}function G$(){}function zre(){}function K$(){}function qre(){}function W$(){}function Y$(){}function X$(){}function BI(){}function w5(){}function US(){}function S1(){}function Q$(){}function hk(){}function FI(){}function J$(){}function km(){}function Z$(){}function GS(){o_()}function Hre(){iO()}function ez(){dU()}function tz(){Lce()}function nz(){IA()}function KS(){Xxe()}function WS(){b0()}function rz(){axe()}function iz(){VN()}function b8(){sO()}function Kv(){OO()}function fk(){het()}function sz(){lx()}function Vre(){$ut()}function az(){s7e()}function m8(){Aot()}function RI(){a7e()}function oz(){mlt()}function Ure(){_ot()}function cz(){TE()}function YS(){eft()}function XS(){Zht()}function jI(){Ect()}function Gre(){tft()}function Kre(){Cb()}function Wre(){eq()}function Yre(){Yke()}function Xre(){Nt()}function Qre(){nft()}function Jre(){Lft()}function Zre(){Lot()}function eie(){egt()}function tie(){Mot()}function nie(){gmt()}function rie(){_9e()}function iie(){tp()}function sie(){p1t()}function v8(){Hc()}function aie(){jot()}function dk(){ux()}function Cf(){uke()}function oie(){Sb()}function gk(){lke()}function QS(){z1()}function cie(){YN()}function uie(){tle()}function lie(){lue()}function Sf(){pit()}function hie(){ZH()}function fie(){wU()}function uz(){pi()}function die(){PV()}function lz(){B8e()}function hz(){lce()}function fz(){zU()}function dz(){xke()}function n0(e){nr(e)}function gz(e){this.a=e}function JS(e){this.a=e}function pz(e){this.a=e}function bz(e){this.a=e}function gie(e){this.a=e}function pie(e){this.a=e}function mz(e){this.a=e}function bie(e){this.a=e}function vz(e){this.a=e}function Q2(e){this.a=e}function mie(e){this.a=e}function vie(e){this.a=e}function $I(e){this.a=e}function wie(e){this.a=e}function yie(e){this.a=e}function pk(e){this.a=e}function J2(e){this.a=e}function wz(e){this.a=e}function bk(e){this.a=e}function y5(e){this.a=e}function zI(e){this.a=e}function w8(e){this.a=e}function qI(e){this.b=e}function qg(e){this.c=e}function xie(e){this.a=e}function iy(e){this.a=e}function yz(e){this.a=e}function xz(e){this.a=e}function HI(e){this.a=e}function VI(e){this.a=e}function kz(e){this.a=e}function y8(e){this.a=e}function mk(e){this.a=e}function kie(e){this.a=e}function Ez(e){this.a=e}function Tz(e){this.a=e}function Cz(e){this.a=e}function Sz(e){this.a=e}function jc(e){this.a=e}function vk(e){this.a=e}function wk(e){this.a=e}function $p(){this.a=[]}function Eie(e,t){e.a=t}function Tie(e,t){e.a=t}function Cie(e,t){e.b=t}function Sie(e,t){e.b=t}function _ie(e,t){e.b=t}function _z(e,t){e.j=t}function bwe(e,t){e.g=t}function Az(e,t){e.i=t}function Aie(e,t){e.c=t}function x8(e,t){e.c=t}function mwe(e,t){e.d=t}function k8(e,t){e.d=t}function x(e,t){e.k=t}function m(e,t){e.c=t}function k(e,t){e.c=t}function S(e,t){e.a=t}function M(e,t){e.a=t}function O(e,t){e.f=t}function N(e,t){e.a=t}function $(e,t){e.b=t}function H(e,t){e.d=t}function q(e,t){e.i=t}function Y(e,t){e.o=t}function Z(e,t){e.r=t}function ce(e,t){e.a=t}function ve(e,t){e.b=t}function me(e,t){e.e=t}function Le(e,t){e.f=t}function _e(e,t){e.g=t}function Ee(e,t){e.e=t}function Be(e,t){e.f=t}function Re(e,t){e.f=t}function Ve(e,t){e.a=t}function ct(e,t){e.b=t}function st(e,t){e.n=t}function Ye(e,t){e.a=t}function mt(e,t){e.c=t}function Je(e,t){e.c=t}function Lt(e,t){e.c=t}function Mt(e,t){e.a=t}function ut(e,t){e.a=t}function Wt(e,t){e.d=t}function Tt(e,t){e.d=t}function _n(e,t){e.e=t}function hn(e,t){e.e=t}function Yt(e,t){e.g=t}function Dn(e,t){e.f=t}function ir(e,t){e.j=t}function vr(e,t){e.a=t}function Nn(e,t){e.a=t}function pr(e,t){e.b=t}function Er(e){e.b=e.a}function Mr(e){e.c=e.d.d}function Cr(e){this.a=e}function Or(e){this.a=e}function Wn(e){this.a=e}function br(e){this.a=e}function Sr(e){this.a=e}function Nr(e){this.a=e}function Si(e){this.a=e}function ys(e){this.a=e}function pa(e){this.a=e}function Mi(e){this.a=e}function gi(e){this.a=e}function fs(e){this.a=e}function Fs(e){this.a=e}function xs(e){this.a=e}function Rs(e){this.b=e}function yo(e){this.b=e}function $a(e){this.b=e}function Da(e){this.a=e}function Bo(e){this.a=e}function tr(e){this.c=e}function G(e){this.c=e}function Jn(e){this.c=e}function kr(e){this.d=e}function lr(e){this.a=e}function Vt(e){this.a=e}function Hs(e){this.a=e}function wr(e){this.a=e}function Es(e){this.a=e}function go(e){this.a=e}function $c(e){this.a=e}function za(e){this.a=e}function Sc(e){this.a=e}function ba(e){this.a=e}function xo(e){this.a=e}function lh(e){this.a=e}function Wl(e){this.a=e}function Z2(e){this.a=e}function eb(e){this.a=e}function G0(e){this.a=e}function zp(e){this.a=e}function fd(e){this.a=e}function Wv(e){this.a=e}function sy(e){this.a=e}function E8(e){this.a=e}function x5(e){this.a=e}function T8(e){this.a=e}function ZS(e){this.a=e}function k5(e){this.a=e}function Qd(e){this.a=e}function _1(e){this.a=e}function Jd(e){this.a=e}function Yv(e){this.a=e}function Em(e){this.a=e}function Lz(e){this.a=e}function Lie(e){this.a=e}function Mie(e){this.a=e}function e_(e){this.a=e}function Die(e){this.a=e}function Iie(e){this.a=e}function E5(e){this.a=e}function Mz(e){this.a=e}function yk(e){this.a=e}function UI(e){this.a=e}function t_(e){this.a=e}function Dz(e){this.a=e}function Iz(e){this.a=e}function Oie(e){this.a=e}function qp(e){this.a=e}function n_(e){this.a=e}function GI(e){this.a=e}function Tm(e){this.a=e}function Zd(e){this.e=e}function T5(e){this.a=e}function jWe(e){this.a=e}function C8(e){this.a=e}function vwe(e){this.a=e}function $We(e){this.a=e}function zWe(e){this.a=e}function qWe(e){this.a=e}function HWe(e){this.a=e}function VWe(e){this.a=e}function UWe(e){this.a=e}function GWe(e){this.a=e}function KWe(e){this.a=e}function WWe(e){this.a=e}function YWe(e){this.a=e}function XWe(e){this.a=e}function wwe(e){this.a=e}function QWe(e){this.a=e}function JWe(e){this.a=e}function ZWe(e){this.a=e}function eYe(e){this.a=e}function tYe(e){this.a=e}function nYe(e){this.a=e}function rYe(e){this.a=e}function iYe(e){this.a=e}function sYe(e){this.a=e}function aYe(e){this.a=e}function oYe(e){this.a=e}function cYe(e){this.a=e}function uYe(e){this.a=e}function lYe(e){this.a=e}function hYe(e){this.a=e}function fYe(e){this.a=e}function dYe(e){this.a=e}function gYe(e){this.a=e}function pYe(e){this.a=e}function bYe(e){this.a=e}function mYe(e){this.a=e}function vYe(e){this.a=e}function wYe(e){this.a=e}function yYe(e){this.a=e}function xYe(e){this.a=e}function kYe(e){this.a=e}function EYe(e){this.a=e}function TYe(e){this.a=e}function CYe(e){this.a=e}function SYe(e){this.a=e}function _Ye(e){this.a=e}function AYe(e){this.a=e}function LYe(e){this.a=e}function MYe(e){this.a=e}function DYe(e){this.a=e}function IYe(e){this.a=e}function OYe(e){this.a=e}function NYe(e){this.a=e}function PYe(e){this.c=e}function BYe(e){this.b=e}function FYe(e){this.a=e}function RYe(e){this.a=e}function jYe(e){this.a=e}function $Ye(e){this.a=e}function zYe(e){this.a=e}function qYe(e){this.a=e}function HYe(e){this.a=e}function VYe(e){this.a=e}function UYe(e){this.a=e}function GYe(e){this.a=e}function KYe(e){this.a=e}function WYe(e){this.a=e}function YYe(e){this.a=e}function XYe(e){this.a=e}function QYe(e){this.a=e}function JYe(e){this.a=e}function ZYe(e){this.a=e}function eXe(e){this.a=e}function tXe(e){this.a=e}function nXe(e){this.a=e}function rXe(e){this.a=e}function iXe(e){this.a=e}function sXe(e){this.a=e}function aXe(e){this.a=e}function oXe(e){this.a=e}function cXe(e){this.a=e}function uXe(e){this.a=e}function Hg(e){this.a=e}function C5(e){this.a=e}function lXe(e){this.a=e}function hXe(e){this.a=e}function fXe(e){this.a=e}function dXe(e){this.a=e}function gXe(e){this.a=e}function pXe(e){this.a=e}function bXe(e){this.a=e}function mXe(e){this.a=e}function vXe(e){this.a=e}function wXe(e){this.a=e}function yXe(e){this.a=e}function xXe(e){this.a=e}function kXe(e){this.a=e}function EXe(e){this.a=e}function TXe(e){this.a=e}function CXe(e){this.a=e}function SXe(e){this.a=e}function _Xe(e){this.a=e}function AXe(e){this.a=e}function LXe(e){this.a=e}function MXe(e){this.a=e}function DXe(e){this.a=e}function IXe(e){this.a=e}function OXe(e){this.a=e}function NXe(e){this.a=e}function PXe(e){this.a=e}function Oz(e){this.a=e}function BXe(e){this.f=e}function FXe(e){this.a=e}function RXe(e){this.a=e}function jXe(e){this.a=e}function $Xe(e){this.a=e}function zXe(e){this.a=e}function qXe(e){this.a=e}function HXe(e){this.a=e}function VXe(e){this.a=e}function UXe(e){this.a=e}function GXe(e){this.a=e}function KXe(e){this.a=e}function WXe(e){this.a=e}function YXe(e){this.a=e}function XXe(e){this.a=e}function QXe(e){this.a=e}function JXe(e){this.a=e}function ZXe(e){this.a=e}function eQe(e){this.a=e}function tQe(e){this.a=e}function nQe(e){this.a=e}function rQe(e){this.a=e}function iQe(e){this.a=e}function sQe(e){this.a=e}function aQe(e){this.a=e}function oQe(e){this.a=e}function cQe(e){this.a=e}function uQe(e){this.a=e}function lQe(e){this.a=e}function Nie(e){this.a=e}function ywe(e){this.a=e}function Ui(e){this.b=e}function hQe(e){this.a=e}function fQe(e){this.a=e}function dQe(e){this.a=e}function gQe(e){this.a=e}function pQe(e){this.a=e}function bQe(e){this.a=e}function mQe(e){this.a=e}function vQe(e){this.b=e}function wQe(e){this.a=e}function KI(e){this.a=e}function yQe(e){this.a=e}function xQe(e){this.a=e}function xwe(e){this.c=e}function Nz(e){this.e=e}function Pz(e){this.a=e}function Bz(e){this.a=e}function Pie(e){this.a=e}function kQe(e){this.d=e}function EQe(e){this.a=e}function kwe(e){this.a=e}function Ewe(e){this.a=e}function Xv(e){this.e=e}function Dcn(){this.a=0}function Pr(){Nl(this)}function bt(){Yse(this)}function Bie(){cat(this)}function TQe(){}function Qv(){this.c=LPe}function CQe(e,t){e.b+=t}function Icn(e,t){t.Wb(e)}function Ocn(e){return e.a}function Ncn(e){return e.a}function Pcn(e){return e.a}function Bcn(e){return e.a}function Fcn(e){return e.a}function ue(e){return e.e}function Rcn(){return null}function jcn(){return null}function $cn(){c3e(),wIn()}function zcn(e){e.b.Of(e.e)}function SQe(e){e.b=new nse}function r_(e,t){e.b=t-e.b}function i_(e,t){e.a=t-e.a}function $n(e,t){e.push(t)}function _Qe(e,t){e.sort(t)}function AQe(e,t){t.jd(e.a)}function qcn(e,t){la(t,e)}function Hcn(e,t,n){e.Yd(n,t)}function WI(e,t){e.e=t,t.b=e}function Twe(e){wd(),this.a=e}function LQe(e){wd(),this.a=e}function MQe(e){wd(),this.a=e}function Fie(e){ww(),this.a=e}function DQe(e){Xk(),S0e.le(e)}function Cwe(){Cwe=U,new Pr}function Cm(){Jnt.call(this)}function Swe(){Jnt.call(this)}function _we(){Cm.call(this)}function Rie(){Cm.call(this)}function IQe(){Cm.call(this)}function YI(){Cm.call(this)}function pl(){Cm.call(this)}function S8(){Cm.call(this)}function Qr(){Cm.call(this)}function Xh(){Cm.call(this)}function OQe(){Cm.call(this)}function _c(){Cm.call(this)}function NQe(){Cm.call(this)}function PQe(){this.a=this}function Fz(){this.Bb|=256}function BQe(){this.b=new Utt}function ay(e,t){e.length=t}function Rz(e,t){vt(e.a,t)}function Vcn(e,t){Jxe(e.c,t)}function Ucn(e,t){na(e.b,t)}function Gcn(e,t){oU(e.a,t)}function Kcn(e,t){Fce(e.a,t)}function xk(e,t){Ni(e.e,t)}function _8(e){EU(e.c,e.b)}function Wcn(e,t){e.kc().Nb(t)}function Awe(e){this.a=$4n(e)}function Ks(){this.a=new Pr}function FQe(){this.a=new Pr}function Lwe(){this.a=new net}function jz(){this.a=new bt}function jie(){this.a=new bt}function Mwe(){this.a=new bt}function _f(){this.a=new pm}function Sm(){this.a=new Nut}function Dwe(){this.a=new bm}function Iwe(){this.a=new Sot}function Owe(){this.a=new Rrt}function RQe(){this.a=new bt}function jQe(){this.a=new bt}function $Qe(){this.a=new bt}function Nwe(){this.a=new bt}function zQe(){this.d=new bt}function qQe(){this.a=new Got}function HQe(){this.a=new Ks}function VQe(){this.a=new Pr}function UQe(){this.b=new Pr}function GQe(){this.b=new bt}function Pwe(){this.e=new bt}function KQe(){this.a=new Kre}function WQe(){this.d=new bt}function YQe(){Qat.call(this)}function XQe(){Qat.call(this)}function QQe(){bt.call(this)}function Bwe(){_we.call(this)}function Fwe(){jz.call(this)}function JQe(){Vq.call(this)}function ZQe(){Nwe.call(this)}function s_(){TQe.call(this)}function $ie(){s_.call(this)}function A8(){TQe.call(this)}function Rwe(){A8.call(this)}function eJe(){qwe.call(this)}function tJe(){qwe.call(this)}function nJe(){qwe.call(this)}function rJe(){Hwe.call(this)}function a_(){Wne.call(this)}function jwe(){Wne.call(this)}function bl(){os.call(this)}function iJe(){wJe.call(this)}function sJe(){wJe.call(this)}function aJe(){Pr.call(this)}function oJe(){Pr.call(this)}function cJe(){Pr.call(this)}function zie(){sft.call(this)}function uJe(){Ks.call(this)}function lJe(){Fz.call(this)}function qie(){kye.call(this)}function $we(){Pr.call(this)}function Hie(){kye.call(this)}function Vie(){Pr.call(this)}function hJe(){Pr.call(this)}function zwe(){m5.call(this)}function fJe(){zwe.call(this)}function dJe(){m5.call(this)}function gJe(){J$.call(this)}function qwe(){this.a=new Ks}function pJe(){this.a=new Pr}function bJe(){this.a=new bt}function Hwe(){this.a=new Pr}function L8(){this.a=new os}function mJe(){this.j=new bt}function vJe(){this.a=new bZe}function wJe(){this.a=new Qne}function Vwe(){this.a=new hs}function o_(){o_=U,v0e=new _}function Uie(){Uie=U,w0e=new xJe}function Gie(){Gie=U,y0e=new yJe}function yJe(){pk.call(this,"")}function xJe(){pk.call(this,"")}function kJe(e){Aht.call(this,e)}function EJe(e){Aht.call(this,e)}function Uwe(e){vz.call(this,e)}function Gwe(e){UZe.call(this,e)}function Ycn(e){UZe.call(this,e)}function Xcn(e){Gwe.call(this,e)}function Qcn(e){Gwe.call(this,e)}function Jcn(e){Gwe.call(this,e)}function TJe(e){Toe.call(this,e)}function CJe(e){Toe.call(this,e)}function SJe(e){ait.call(this,e)}function _Je(e){p3e.call(this,e)}function c_(e){Xz.call(this,e)}function Kwe(e){Xz.call(this,e)}function AJe(e){Xz.call(this,e)}function Wwe(e){y9n.call(this,e)}function Ywe(e){Wwe.call(this,e)}function Ac(e){_st.call(this,e)}function LJe(e){Ac.call(this,e)}function M8(){wk.call(this,{})}function MJe(){MJe=U,d6t=new W}function $z(){$z=U,E0e=new Ant}function DJe(){DJe=U,USe=new T}function Xwe(){Xwe=U,GSe=new ae}function zz(){zz=U,NL=new de}function Kie(e){Ok(),this.a=e}function Wie(e){E7e(),this.a=e}function Jv(e){Iae(),this.f=e}function Yie(e){Iae(),this.f=e}function IJe(e){git(),this.a=e}function OJe(e){e.b=null,e.c=0}function Zcn(e,t){e.e=t,gbt(e,t)}function eun(e,t){e.a=t,okn(e)}function Xie(e,t,n){e.a[t.g]=n}function tun(e,t,n){k8n(n,e,t)}function nun(e,t){Qfn(t.i,e.n)}function NJe(e,t){xyn(e).Cd(t)}function run(e,t){e.a.ec().Mc(t)}function PJe(e,t){return e.g-t.g}function iun(e,t){return e*e/t}function Rt(e){return nr(e),e}function ze(e){return nr(e),e}function XI(e){return nr(e),e}function sun(e){return new vk(e)}function aun(e){return new yy(e)}function Qwe(e){return nr(e),e}function oun(e){return nr(e),e}function qz(e){Ac.call(this,e)}function tc(e){Ac.call(this,e)}function BJe(e){Ac.call(this,e)}function Qie(e){_st.call(this,e)}function kk(e){Ac.call(this,e)}function Yn(e){Ac.call(this,e)}function nc(e){Ac.call(this,e)}function FJe(e){Ac.call(this,e)}function D8(e){Ac.call(this,e)}function Hp(e){Ac.call(this,e)}function Vp(e){Ac.call(this,e)}function I8(e){Ac.call(this,e)}function dd(e){Ac.call(this,e)}function Jie(e){Ac.call(this,e)}function ri(e){Ac.call(this,e)}function Il(e){nr(e),this.a=e}function Jwe(e){return Um(e),e}function u_(e){l5e(e,e.length)}function l_(e){return e.b==e.c}function oy(e){return!!e&&e.b}function cun(e){return!!e&&e.k}function uun(e){return!!e&&e.j}function lun(e,t,n){e.c.Ef(t,n)}function RJe(e,t){e.be(t),t.ae(e)}function O8(e){wd(),this.a=Xr(e)}function Zie(){this.a=ei(Xr(Co))}function jJe(){throw ue(new Qr)}function hun(){throw ue(new Qr)}function Zwe(){throw ue(new Qr)}function $Je(){throw ue(new Qr)}function fun(){throw ue(new Qr)}function dun(){throw ue(new Qr)}function Hz(){Hz=U,Xk()}function Up(){Nr.call(this,"")}function h_(){Nr.call(this,"")}function tb(){Nr.call(this,"")}function S5(){Nr.call(this,"")}function e3e(e){tc.call(this,e)}function t3e(e){tc.call(this,e)}function gd(e){Yn.call(this,e)}function Ek(e){$a.call(this,e)}function zJe(e){Ek.call(this,e)}function ese(e){jq.call(this,e)}function tse(e){Nye.call(this,e,0)}function nse(){G5e.call(this,12,3)}function le(e,t){return yot(e,t)}function Vz(e,t){return joe(e,t)}function gun(e,t){return e.a-t.a}function pun(e,t){return e.a-t.a}function bun(e,t){return e.a-t.a}function mun(e,t){return t in e.a}function qJe(e){return e.a?e.b:0}function vun(e){return e.a?e.b:0}function wun(e,t,n){t.Cd(e.a[n])}function yun(e,t,n){t.Pe(e.a[n])}function xun(e,t){e.b=new Eo(t)}function kun(e,t){return e.b=t,e}function HJe(e,t){return e.c=t,e}function VJe(e,t){return e.f=t,e}function Eun(e,t){return e.g=t,e}function n3e(e,t){return e.a=t,e}function r3e(e,t){return e.f=t,e}function Tun(e,t){return e.k=t,e}function i3e(e,t){return e.a=t,e}function Cun(e,t){return e.e=t,e}function s3e(e,t){return e.e=t,e}function Sun(e,t){return e.f=t,e}function _un(e,t){e.b=!0,e.d=t}function Aun(e,t){return e.b-t.b}function Lun(e,t){return e.g-t.g}function Mun(e,t){return e?0:t-1}function UJe(e,t){return e?0:t-1}function Dun(e,t){return e?t-1:0}function Iun(e,t){return e.s-t.s}function Oun(e,t){return t.rg(e)}function Zv(e,t){return e.b=t,e}function Uz(e,t){return e.a=t,e}function ew(e,t){return e.c=t,e}function tw(e,t){return e.d=t,e}function nw(e,t){return e.e=t,e}function a3e(e,t){return e.f=t,e}function f_(e,t){return e.a=t,e}function Tk(e,t){return e.b=t,e}function Ck(e,t){return e.c=t,e}function Qt(e,t){return e.c=t,e}function yn(e,t){return e.b=t,e}function Jt(e,t){return e.d=t,e}function Zt(e,t){return e.e=t,e}function Nun(e,t){return e.f=t,e}function en(e,t){return e.g=t,e}function tn(e,t){return e.a=t,e}function nn(e,t){return e.i=t,e}function rn(e,t){return e.j=t,e}function Pun(e,t){Cb(),Mc(t,e)}function Bun(e,t,n){Jdn(e.a,t,n)}function Gz(e){dae.call(this,e)}function GJe(e){t5n.call(this,e)}function KJe(e){Aat.call(this,e)}function o3e(e){Aat.call(this,e)}function nb(e){Lw.call(this,e)}function WJe(e){noe.call(this,e)}function YJe(e){noe.call(this,e)}function XJe(){bye.call(this,"")}function qa(){this.a=0,this.b=0}function QJe(){this.b=0,this.a=0}function JJe(e,t){e.b=0,My(e,t)}function ZJe(e,t){return e.k=t,e}function Fun(e,t){return e.j=t,e}function Run(e,t){e.c=t,e.b=!0}function eZe(){eZe=U,S6t=Y8n()}function rb(){rb=U,w_t=a8n()}function tZe(){tZe=U,La=vxn()}function c3e(){c3e=U,Qb=hE()}function Sk(){Sk=U,APe=o8n()}function nZe(){nZe=U,rAt=c8n()}function u3e(){u3e=U,tu=ikn()}function K0(e){return e.e&&e.e()}function rZe(e){return e.l|e.m<<22}function iZe(e,t){return e.c._b(t)}function sZe(e,t){return i1t(e.b,t)}function rse(e){return e?e.d:null}function jun(e){return e?e.g:null}function $un(e){return e?e.i:null}function _m(e){return Gg(e),e.o}function _5(e,t){return e.a+=t,e}function ise(e,t){return e.a+=t,e}function Gp(e,t){return e.a+=t,e}function rw(e,t){return e.a+=t,e}function l3e(e,t){for(;e.Bd(t););}function Kz(e){this.a=new N8(e)}function aZe(){throw ue(new Qr)}function oZe(){throw ue(new Qr)}function cZe(){throw ue(new Qr)}function uZe(){throw ue(new Qr)}function lZe(){throw ue(new Qr)}function hZe(){throw ue(new Qr)}function Kp(e){this.a=new Pae(e)}function fZe(){this.a=new UA(EIe)}function dZe(){this.b=new UA(qDe)}function gZe(){this.a=new UA(KIe)}function pZe(){this.b=new UA(pge)}function bZe(){this.b=new UA(pge)}function Wz(e){this.a=0,this.b=e}function h3e(e){Gvt(),IIn(this,e)}function _k(e){return fb(e),e.a}function QI(e){return e.b!=e.d.c}function f3e(e,t){return e.d[t.p]}function mZe(e,t){return YCn(e,t)}function d3e(e,t,n){e.splice(t,n)}function A5(e,t){for(;e.Re(t););}function vZe(e){e.c?Ibt(e):Obt(e)}function wZe(){throw ue(new Qr)}function yZe(){throw ue(new Qr)}function xZe(){throw ue(new Qr)}function kZe(){throw ue(new Qr)}function EZe(){throw ue(new Qr)}function TZe(){throw ue(new Qr)}function CZe(){throw ue(new Qr)}function SZe(){throw ue(new Qr)}function _Ze(){throw ue(new Qr)}function AZe(){throw ue(new Qr)}function zun(){throw ue(new _c)}function qun(){throw ue(new _c)}function JI(e){this.a=new LZe(e)}function LZe(e){Gwn(this,e,T9n())}function ZI(e){return!e||oat(e)}function eO(e){return nd[e]!=-1}function Hun(){aK!=0&&(aK=0),oK=-1}function MZe(){m0e==null&&(m0e=[])}function tO(e,t){q5.call(this,e,t)}function Ak(e,t){tO.call(this,e,t)}function DZe(e,t){this.a=e,this.b=t}function IZe(e,t){this.a=e,this.b=t}function OZe(e,t){this.a=e,this.b=t}function NZe(e,t){this.a=e,this.b=t}function PZe(e,t){this.a=e,this.b=t}function BZe(e,t){this.a=e,this.b=t}function FZe(e,t){this.a=e,this.b=t}function Lk(e,t){this.e=e,this.d=t}function g3e(e,t){this.b=e,this.c=t}function RZe(e,t){this.b=e,this.a=t}function jZe(e,t){this.b=e,this.a=t}function $Ze(e,t){this.b=e,this.a=t}function zZe(e,t){this.b=e,this.a=t}function qZe(e,t){this.a=e,this.b=t}function sse(e,t){this.a=e,this.b=t}function HZe(e,t){this.a=e,this.f=t}function iw(e,t){this.g=e,this.i=t}function Ur(e,t){this.f=e,this.g=t}function VZe(e,t){this.b=e,this.c=t}function UZe(e){Tye(e.dc()),this.c=e}function Vun(e,t){this.a=e,this.b=t}function GZe(e,t){this.a=e,this.b=t}function KZe(e){this.a=l(Xr(e),15)}function p3e(e){this.a=l(Xr(e),15)}function WZe(e){this.a=l(Xr(e),85)}function Yz(e){this.b=l(Xr(e),85)}function Xz(e){this.b=l(Xr(e),51)}function Qz(){this.q=new b.Date}function ase(e,t){this.a=e,this.b=t}function YZe(e,t){return Hu(e.b,t)}function nO(e,t){return e.b.Hc(t)}function XZe(e,t){return e.b.Ic(t)}function QZe(e,t){return e.b.Qc(t)}function JZe(e,t){return e.b.Hc(t)}function ZZe(e,t){return e.c.uc(t)}function eet(e,t){return Pi(e.c,t)}function W0(e,t){return e.a._b(t)}function tet(e,t){return e>t&&t0}function fse(e,t){return iu(e,t)<0}function vet(e,t){return Aae(e.a,t)}function uln(e,t){xot.call(this,e,t)}function k3e(e){Kae(),ait.call(this,e)}function E3e(e,t){gst(e,e.length,t)}function aO(e,t){qst(e,e.length,t)}function y_(e,t){return e.a.get(t)}function wet(e,t){return Hu(e.e,t)}function T3e(e){return nr(e),!1}function C3e(e){this.a=l(Xr(e),229)}function aq(e){kn.call(this,e,21)}function oq(e,t){Ur.call(this,e,t)}function dse(e,t){Ur.call(this,e,t)}function yet(e,t){this.b=e,this.a=t}function cq(e,t){this.d=e,this.e=t}function xet(e,t){this.a=e,this.b=t}function ket(e,t){this.a=e,this.b=t}function Eet(e,t){this.a=e,this.b=t}function Tet(e,t){this.a=e,this.b=t}function B8(e,t){this.a=e,this.b=t}function Cet(e,t){this.b=e,this.a=t}function S3e(e,t){this.b=e,this.a=t}function _3e(e,t){Ur.call(this,e,t)}function A3e(e,t){Ur.call(this,e,t)}function L5(e,t){Ur.call(this,e,t)}function gse(e,t){Ur.call(this,e,t)}function pse(e,t){Ur.call(this,e,t)}function bse(e,t){Ur.call(this,e,t)}function uq(e,t){Ur.call(this,e,t)}function L3e(e,t){this.b=e,this.a=t}function lq(e,t){Ur.call(this,e,t)}function M3e(e,t){this.b=e,this.a=t}function hq(e,t){Ur.call(this,e,t)}function _et(e,t){this.b=e,this.a=t}function D3e(e,t){Ur.call(this,e,t)}function mse(e,t){Ur.call(this,e,t)}function oO(e,t){Ur.call(this,e,t)}function x_(e,t,n){e.splice(t,0,n)}function lln(e,t,n){e.Mb(n)&&t.Cd(n)}function hln(e,t,n){t.Pe(e.a.Ye(n))}function fln(e,t,n){t.Dd(e.a.Ze(n))}function dln(e,t,n){t.Cd(e.a.Kb(n))}function gln(e,t){return vl(e.c,t)}function pln(e,t){return vl(e.e,t)}function fq(e,t){Ur.call(this,e,t)}function dq(e,t){Ur.call(this,e,t)}function k_(e,t){Ur.call(this,e,t)}function I3e(e,t){Ur.call(this,e,t)}function Ws(e,t){Ur.call(this,e,t)}function gq(e,t){Ur.call(this,e,t)}function Aet(e,t){this.a=e,this.b=t}function Let(e,t){this.a=e,this.b=t}function Met(e,t){this.a=e,this.b=t}function Det(e,t){this.a=e,this.b=t}function Iet(e,t){this.a=e,this.b=t}function Oet(e,t){this.a=e,this.b=t}function Net(e,t){this.b=e,this.a=t}function Pet(e,t){this.b=e,this.a=t}function O3e(e,t){this.b=e,this.a=t}function Ik(e,t){this.c=e,this.d=t}function Bet(e,t){this.e=e,this.d=t}function Fet(e,t){this.a=e,this.b=t}function Ret(e,t){this.a=e,this.b=t}function jet(e,t){this.a=e,this.b=t}function $et(e,t){this.b=e,this.a=t}function zet(e,t){this.b=t,this.c=e}function pq(e,t){Ur.call(this,e,t)}function cO(e,t){Ur.call(this,e,t)}function vse(e,t){Ur.call(this,e,t)}function N3e(e,t){Ur.call(this,e,t)}function E_(e,t){Ur.call(this,e,t)}function wse(e,t){Ur.call(this,e,t)}function yse(e,t){Ur.call(this,e,t)}function uO(e,t){Ur.call(this,e,t)}function P3e(e,t){Ur.call(this,e,t)}function xse(e,t){Ur.call(this,e,t)}function T_(e,t){Ur.call(this,e,t)}function B3e(e,t){Ur.call(this,e,t)}function C_(e,t){Ur.call(this,e,t)}function S_(e,t){Ur.call(this,e,t)}function uy(e,t){Ur.call(this,e,t)}function kse(e,t){Ur.call(this,e,t)}function Ese(e,t){Ur.call(this,e,t)}function F3e(e,t){Ur.call(this,e,t)}function lO(e,t){Ur.call(this,e,t)}function M5(e,t){Ur.call(this,e,t)}function Tse(e,t){Ur.call(this,e,t)}function bq(e,t){Ur.call(this,e,t)}function hO(e,t){Ur.call(this,e,t)}function ly(e,t){Ur.call(this,e,t)}function mq(e,t){Ur.call(this,e,t)}function R3e(e,t){Ur.call(this,e,t)}function Cse(e,t){Ur.call(this,e,t)}function Sse(e,t){Ur.call(this,e,t)}function _se(e,t){Ur.call(this,e,t)}function Ase(e,t){Ur.call(this,e,t)}function Lse(e,t){Ur.call(this,e,t)}function Mse(e,t){Ur.call(this,e,t)}function Dse(e,t){Ur.call(this,e,t)}function qet(e,t){this.b=e,this.a=t}function j3e(e,t){Ur.call(this,e,t)}function Het(e,t){this.a=e,this.b=t}function Vet(e,t){this.a=e,this.b=t}function Uet(e,t){this.a=e,this.b=t}function $3e(e,t){Ur.call(this,e,t)}function z3e(e,t){Ur.call(this,e,t)}function Get(e,t){this.a=e,this.b=t}function bln(e,t){return jk(),t!=e}function fO(e){return mr(e.a),e.b}function Ise(e){return EEn(e,e.c),e}function Ket(){return eZe(),new S6t}function Wet(){Yq(),this.a=new i4e}function Yet(){IU(),this.a=new Ks}function Xet(){foe(),this.b=new Ks}function Qet(e,t){this.b=e,this.d=t}function Jet(e,t){this.a=e,this.b=t}function Zet(e,t){this.a=e,this.b=t}function ett(e,t){this.a=e,this.b=t}function ttt(e,t){this.b=e,this.a=t}function q3e(e,t){Ur.call(this,e,t)}function H3e(e,t){Ur.call(this,e,t)}function vq(e,t){Ur.call(this,e,t)}function ow(e,t){Ur.call(this,e,t)}function Ose(e,t){Ur.call(this,e,t)}function wq(e,t){Ur.call(this,e,t)}function V3e(e,t){Ur.call(this,e,t)}function U3e(e,t){Ur.call(this,e,t)}function dO(e,t){Ur.call(this,e,t)}function G3e(e,t){Ur.call(this,e,t)}function Nse(e,t){Ur.call(this,e,t)}function yq(e,t){Ur.call(this,e,t)}function Pse(e,t){Ur.call(this,e,t)}function Bse(e,t){Ur.call(this,e,t)}function Fse(e,t){Ur.call(this,e,t)}function Rse(e,t){Ur.call(this,e,t)}function K3e(e,t){Ur.call(this,e,t)}function jse(e,t){Ur.call(this,e,t)}function W3e(e,t){Ur.call(this,e,t)}function gO(e,t){Ur.call(this,e,t)}function $se(e,t){Ur.call(this,e,t)}function Y3e(e,t){Ur.call(this,e,t)}function pO(e,t){Ur.call(this,e,t)}function X3e(e,t){Ur.call(this,e,t)}function ntt(e,t){this.b=e,this.a=t}function rtt(e,t){this.b=e,this.a=t}function itt(e,t){this.b=e,this.a=t}function stt(e,t){this.b=e,this.a=t}function Q3e(e,t){this.a=e,this.b=t}function att(e,t){this.a=e,this.b=t}function ott(e,t){this.a=e,this.b=t}function lt(e,t){this.a=e,this.b=t}function __(e,t){Ur.call(this,e,t)}function bO(e,t){Ur.call(this,e,t)}function F8(e,t){Ur.call(this,e,t)}function A_(e,t){Ur.call(this,e,t)}function mO(e,t){Ur.call(this,e,t)}function zse(e,t){Ur.call(this,e,t)}function xq(e,t){Ur.call(this,e,t)}function L_(e,t){Ur.call(this,e,t)}function qse(e,t){Ur.call(this,e,t)}function kq(e,t){Ur.call(this,e,t)}function D5(e,t){Ur.call(this,e,t)}function vO(e,t){Ur.call(this,e,t)}function M_(e,t){Ur.call(this,e,t)}function D_(e,t){Ur.call(this,e,t)}function wO(e,t){Ur.call(this,e,t)}function Eq(e,t){Ur.call(this,e,t)}function I5(e,t){Ur.call(this,e,t)}function Hse(e,t){Ur.call(this,e,t)}function ctt(e,t){Ur.call(this,e,t)}function Tq(e,t){Ur.call(this,e,t)}function utt(e,t){this.a=e,this.b=t}function ltt(e,t){this.a=e,this.b=t}function htt(e,t){this.a=e,this.b=t}function ftt(e,t){this.a=e,this.b=t}function dtt(e,t){this.a=e,this.b=t}function gtt(e,t){this.a=e,this.b=t}function ca(e,t){this.a=e,this.b=t}function ptt(e,t){this.a=e,this.b=t}function btt(e,t){this.a=e,this.b=t}function mtt(e,t){this.a=e,this.b=t}function vtt(e,t){this.a=e,this.b=t}function wtt(e,t){this.a=e,this.b=t}function ytt(e,t){this.a=e,this.b=t}function xtt(e,t){this.b=e,this.a=t}function ktt(e,t){this.b=e,this.a=t}function Ett(e,t){this.b=e,this.a=t}function Ttt(e,t){this.b=e,this.a=t}function Ctt(e,t){this.a=e,this.b=t}function Stt(e,t){this.a=e,this.b=t}function Cq(e,t){Ur.call(this,e,t)}function _tt(e,t){this.a=e,this.b=t}function Att(e,t){this.a=e,this.b=t}function R8(e,t){Ur.call(this,e,t)}function Ltt(e,t){this.f=e,this.c=t}function J3e(e,t){return vl(e.g,t)}function mln(e,t){return vl(t.b,e)}function Mtt(e,t){return Kce(e.a,t)}function vln(e,t){return-e.b.af(t)}function wln(e,t){e&&ki(lF,e,t)}function Z3e(e,t){e.i=null,xV(e,t)}function yln(e,t,n){xgt(t,jue(e,n))}function xln(e,t,n){xgt(t,jue(e,n))}function kln(e,t){XTn(e.a,l(t,58))}function Dtt(e,t){Gvn(e.a,l(t,12))}function Sq(e,t){this.a=e,this.b=t}function Itt(e,t){this.a=e,this.b=t}function Ott(e,t){this.a=e,this.b=t}function Ntt(e,t){this.a=e,this.b=t}function Ptt(e,t){this.a=e,this.b=t}function Btt(e,t){this.d=e,this.b=t}function Ftt(e,t){this.e=e,this.a=t}function yO(e,t){this.b=e,this.c=t}function eye(e,t){this.i=e,this.g=t}function tye(e,t){this.d=e,this.e=t}function Eln(e,t){own(new or(e),t)}function _q(e){return FN(e.c,e.b)}function hc(e){return e?e.md():null}function qe(e){return e??null}function Ia(e){return typeof e===Ile}function hy(e){return typeof e===Cx}function fy(e){return typeof e===Qke}function cw(e,t){return iu(e,t)==0}function Aq(e,t){return iu(e,t)>=0}function I_(e,t){return iu(e,t)!=0}function Lq(e,t){return T3n(e.Kc(),t)}function ab(e,t){return e.Rd().Xb(t)}function Rtt(e){return Ql(e),e.d.gc()}function Mq(e){return V_(e==null),e}function O_(e,t){return e.a+=""+t,e}function Xo(e,t){return e.a+=""+t,e}function N_(e,t){return e.a+=""+t,e}function wu(e,t){return e.a+=""+t,e}function hi(e,t){return e.a+=""+t,e}function nye(e,t){return e.a+=""+t,e}function Tln(e){return""+(nr(e),e)}function jtt(e){Nl(this),bA(this,e)}function $tt(){U5e(),Q4e.call(this)}function ztt(e,t){n5e.call(this,e,t)}function qtt(e,t){n5e.call(this,e,t)}function Dq(e,t){n5e.call(this,e,t)}function ko(e,t){Cs(e,t,e.c.b,e.c)}function O5(e,t){Cs(e,t,e.a,e.a.a)}function rye(e){return Sn(e,0),null}function Htt(){this.b=0,this.a=!1}function Vtt(){this.b=0,this.a=!1}function Utt(){this.b=new N8(Ay(12))}function Gtt(){Gtt=U,y7t=Kr(eue())}function Ktt(){Ktt=U,q8t=Kr(rbt())}function Wtt(){Wtt=U,hTt=Kr(Bft())}function iye(){iye=U,Cwe(),KSe=new Pr}function Y0(e){return e.a=0,e.b=0,e}function Ytt(e,t){return e.a=t.g+1,e}function Vse(e,t){my.call(this,e,t)}function pn(e,t){vs.call(this,e,t)}function N5(e,t){eye.call(this,e,t)}function Xtt(e,t){TO.call(this,e,t)}function Use(e,t){mE.call(this,e,t)}function wi(e,t){iq(),ki(kY,e,t)}function Qtt(e,t){e.q.setTime(Fm(t))}function Cln(e){b.clearTimeout(e)}function Sln(e){return Xr(e),new P_(e)}function Jtt(e,t){return qe(e)===qe(t)}function Ztt(e,t){return e.a.a.a.cc(t)}function Gse(e,t){return tf(e.a,0,t)}function sye(e){return Lgn(l(e,74))}function j8(e){return ua((nr(e),e))}function _ln(e){return ua((nr(e),e))}function ent(e){return qu(e.l,e.m,e.h)}function aye(e,t){return ru(e.a,t.a)}function Aln(e,t){return $st(e.a,t.a)}function Lln(e,t){return Yi(e.a,t.a)}function pd(e,t){return e.indexOf(t)}function Mln(e,t){return e.j[t.p]==2}function uw(e,t){return e==t?0:e?1:-1}function Iq(e){return e<10?"0"+e:""+e}function wc(e){return typeof e===Qke}function Dln(e){return e==s3||e==o4}function Iln(e){return e==s3||e==a4}function tnt(e,t){return ru(e.g,t.g)}function oye(e){return gc(e.b.b,e,0)}function nnt(){sH.call(this,0,0,0,0)}function bd(){wr.call(this,new e2)}function cye(e,t){nE(e,0,e.length,t)}function Oln(e,t){return vt(e.a,t),t}function Nln(e,t){return u0(),t.a+=e}function Pln(e,t){return u0(),t.a+=e}function Bln(e,t){return u0(),t.c+=e}function Fln(e,t){return vt(e.c,t),e}function uye(e,t){return Dh(e.a,t),e}function rnt(e){this.a=Ket(),this.b=e}function int(e){this.a=Ket(),this.b=e}function Eo(e){this.a=e.a,this.b=e.b}function P_(e){this.a=e,GS.call(this)}function snt(e){this.a=e,GS.call(this)}function $8(){ef.call(this,0,0,0,0)}function Oq(e){return Dh(new Xs,e)}function ant(e){return EH(l(e,123))}function hh(e){return e.vh()&&e.wh()}function P5(e){return e!=Z1&&e!=Wb}function Ug(e){return e==uc||e==vc}function B5(e){return e==wf||e==Q1}function ont(e){return e==G6||e==U6}function Rln(e,t){return ru(e.g,t.g)}function cnt(e,t){return new mE(t,e)}function jln(e,t){return new mE(t,e)}function lye(e){return adn(e.b.Kc(),e.a)}function Kse(e,t){CE(e,t),lE(e,e.D)}function Wse(e,t,n){dV(e,t),fV(e,n)}function F5(e,t,n){Dw(e,t),Mw(e,n)}function Qh(e,t,n){Uu(e,t),Gu(e,n)}function xO(e,t,n){aE(e,t),cE(e,n)}function kO(e,t,n){oE(e,t),uE(e,n)}function unt(e,t,n){Gye.call(this,e,t,n)}function hye(e){Ltt.call(this,e,!0)}function lnt(){oq.call(this,"Tail",3)}function hnt(){oq.call(this,"Head",1)}function ob(e){Cd(),y3n.call(this,e)}function lw(e){sH.call(this,e,e,e,e)}function Yse(e){e.c=We(wa,Rn,1,0,5,1)}function fye(e){return e.b&&gle(e),e.a}function dye(e){return e.b&&gle(e),e.c}function $ln(e,t){G1||(e.b=t)}function zln(e,t){return e[e.length]=t}function qln(e,t){return e[e.length]=t}function Hln(e,t){return Ly(t,M1(e))}function Vln(e,t){return Ly(t,M1(e))}function Uln(e,t){return vV(Uae(e.d),t)}function Gln(e,t){return vV(Uae(e.g),t)}function Kln(e,t){return vV(Uae(e.j),t)}function Ha(e,t){vs.call(this,e.b,t)}function Wln(e,t){qr(du(e.a),Iot(t))}function Yln(e,t){qr(Xl(e.a),Oot(t))}function Xln(e,t,n){Qh(n,n.i+e,n.j+t)}function fnt(e,t,n){Ts(e.c[t.g],t.g,n)}function Qln(e,t,n){l(e.c,71).Gi(t,n)}function Xse(e,t,n){return Ts(e,t,n),n}function dnt(e){Vu(e.Sf(),new Mie(e))}function R5(e){return e!=null?es(e):0}function Jln(e){return e==null?0:es(e)}function B_(e){Di(),Xv.call(this,e)}function gnt(e){this.a=e,_4e.call(this,e)}function A1(){A1=U,b.Math.log(2)}function Jh(){Jh=U,Sg=(bet(),C_t)}function pnt(){pnt=U,Mde=new LA(Vge)}function Jr(){Jr=U,new bnt,new bt}function bnt(){new Pr,new Pr,new Pr}function Zln(){throw ue(new Hp(Q5t))}function ehn(){throw ue(new Hp(Q5t))}function thn(){throw ue(new Hp(J5t))}function nhn(){throw ue(new Hp(J5t))}function Qse(e){this.a=e,Yz.call(this,e)}function Jse(e){this.a=e,Yz.call(this,e)}function mnt(e,t){ww(),this.a=e,this.b=t}function rhn(e,t){Xr(t),V5(e).Jc(new ie)}function Vs(e,t){Lae(e.c,e.c.length,t)}function Lc(e){return e.at?1:0}function pye(e,t){return iu(e,t)>0?e:t}function qu(e,t,n){return{l:e,m:t,h:n}}function ihn(e,t){e.a!=null&&Dtt(t,e.a)}function shn(e){po(e,null),Fa(e,null)}function ahn(e,t,n){return ki(e.g,n,t)}function j5(e,t,n){return R8e(t,n,e.c)}function ohn(e,t,n){return ki(e.k,n,t)}function chn(e,t,n){return KMn(e,t,n),n}function uhn(e,t){return Sh(),t.n.b+=e}function wnt(e){R5e.call(this),this.b=e}function bye(e){r4e.call(this),this.a=e}function ynt(){oq.call(this,"Range",2)}function Nq(e){this.b=e,this.a=new bt}function xnt(e){this.b=new Nu,this.a=e}function knt(e){e.a=new _t,e.c=new _t}function Ent(e){e.a=new Pr,e.d=new Pr}function Tnt(e){doe(e,null),goe(e,null)}function Cnt(e,t){return YMn(e.a,t,null)}function lhn(e,t){return ki(e.a,t.a,t)}function Ja(e){return new lt(e.a,e.b)}function mye(e){return new lt(e.c,e.d)}function hhn(e){return new lt(e.c,e.d)}function F_(e,t){return oMn(e.c,e.b,t)}function De(e,t){return e!=null&&iue(e,t)}function Zse(e,t){return eyn(e.Kc(),t)!=-1}function Pq(e){return e.Ob()?e.Pb():null}function fhn(e){this.b=(Cn(),new tr(e))}function vye(e){this.a=e,Pr.call(this)}function Snt(){TO.call(this,null,null)}function _nt(){qq.call(this,null,null)}function Ant(){Ur.call(this,"INSTANCE",0)}function Lnt(){mxe(),this.a=new UA(gAe)}function Mnt(e){return If(e,0,e.length)}function dhn(e,t){return new Wnt(e.Kc(),t)}function wye(e,t){return e.a.Bc(t)!=null}function Dnt(e,t){$r(e),e.Gc(l(t,15))}function ghn(e,t,n){e.c.bd(t,l(n,136))}function phn(e,t,n){e.c.Ui(t,l(n,136))}function Int(e,t){e.c&&($4e(t),iot(t))}function bhn(e,t){e.q.setHours(t),XA(e,t)}function mhn(e,t){dw(t,e.a.a.a,e.a.a.b)}function vhn(e,t,n,r){Ts(e.a[t.g],n.g,r)}function eae(e,t,n){return e.a[t.g][n.g]}function whn(e,t){return e.e[t.c.p][t.p]}function yhn(e,t){return e.c[t.c.p][t.p]}function L1(e,t){return e.a[t.c.p][t.p]}function xhn(e,t){return e.j[t.p]=ITn(t)}function tae(e,t){return e.a.Bc(t)!=null}function khn(e,t){return ze(Ge(t.a))<=e}function Ehn(e,t){return ze(Ge(t.a))>=e}function Thn(e,t){return E6e(e.f,t.Pg())}function z8(e,t){return e.a*t.a+e.b*t.b}function Chn(e,t){return e.a0?t/(e*e):t*100}function Xhn(e,t){return e>0?t*t/e:t*t*100}function dy(e,t){return l(B1(e.a,t),34)}function Qhn(e,t){return Cb(),xn(e,t.e,t)}function Jhn(e,t,n){return tq(),n.Mg(e,t)}function Zhn(e){return tp(),e.e.a+e.f.a/2}function efn(e,t,n){return tp(),n.e.a-e*t}function tfn(e){return tp(),e.e.b+e.f.b/2}function nfn(e,t,n){return tp(),n.e.b-e*t}function crt(e){e.d=new srt(e),e.e=new Pr}function urt(){this.a=new Cw,this.b=new Cw}function lrt(e){this.c=e,this.a=1,this.b=1}function hrt(e){Mle(),SQe(this),this.Ff(e)}function rfn(e,t,n){ZH(),e.pf(t)&&n.Cd(e)}function ifn(e,t,n){return vt(t,k1t(e,n))}function dw(e,t,n){return e.a+=t,e.b+=n,e}function sfn(e,t,n){return e.a*=t,e.b*=n,e}function Fye(e,t){return e.a=t.a,e.b=t.b,e}function Hq(e){return e.a=-e.a,e.b=-e.b,e}function z_(e,t,n){return e.a-=t,e.b-=n,e}function frt(e){os.call(this),fA(this,e)}function drt(){Ur.call(this,"GROW_TREE",0)}function grt(){Ur.call(this,"POLYOMINO",0)}function dh(e,t,n){xl.call(this,e,t,n,2)}function afn(e,t,n){_A(du(e.a),t,Iot(n))}function prt(e,t){w_(),TO.call(this,e,t)}function Rye(e,t){Wp(),qq.call(this,e,t)}function brt(e,t){Wp(),Rye.call(this,e,t)}function mrt(e,t){Wp(),qq.call(this,e,t)}function ofn(e,t){return e.c.Fc(l(t,136))}function cfn(e,t,n){_A(Xl(e.a),t,Oot(n))}function vrt(e){this.c=e,Uu(e,0),Gu(e,0)}function oae(e,t){Jh(),cH.call(this,e,t)}function wrt(e,t){Jh(),oae.call(this,e,t)}function jye(e,t){Jh(),oae.call(this,e,t)}function $ye(e,t){Jh(),cH.call(this,e,t)}function yrt(e,t){Jh(),jye.call(this,e,t)}function xrt(e,t){Jh(),$ye.call(this,e,t)}function krt(e,t){Jh(),cH.call(this,e,t)}function ufn(e,t,n){return t.zl(e.e,e.c,n)}function lfn(e,t,n){return t.Al(e.e,e.c,n)}function zye(e,t,n){return VU(lN(e,t),n)}function cae(e,t){return yb(e.e,l(t,54))}function hfn(e){return e==null?null:BDn(e)}function ffn(e){return e==null?null:L9n(e)}function dfn(e){return e==null?null:xc(e)}function gfn(e){return e==null?null:xc(e)}function Bt(e){return V_(e==null||hy(e)),e}function Ge(e){return V_(e==null||fy(e)),e}function ei(e){return V_(e==null||Ia(e)),e}function Gg(e){e.o==null&&oTn(e)}function qye(e){if(!e)throw ue(new YI)}function pfn(e){if(!e)throw ue(new Rie)}function mr(e){if(!e)throw ue(new _c)}function gy(e){if(!e)throw ue(new pl)}function Ert(e){if(!e)throw ue(new Xh)}function Fk(){Fk=U,fF=new iJe,new sJe}function H5(){H5=U,Y6=new Ui("root")}function Hye(){sft.call(this),this.Bb|=Io}function bfn(e,t){this.d=e,Mr(this),this.b=t}function Vye(e,t){Poe.call(this,e),this.a=t}function Uye(e,t){Poe.call(this,e),this.a=t}function Gye(e,t,n){YH.call(this,e,t,n,null)}function Trt(e,t,n){YH.call(this,e,t,n,null)}function _O(e,t){this.c=e,Lk.call(this,e,t)}function q_(e,t){this.a=e,_O.call(this,e,t)}function Kye(e){this.q=new b.Date(Fm(e))}function Crt(e){return e>8?0:e+1}function Srt(e,t){G1||vt(e.a,t)}function mfn(e,t){return sO(),bE(t.d.i,e)}function vfn(e,t){return lx(),new nmt(t,e)}function wfn(e,t,n){return e.Ne(t,n)<=0?n:t}function yfn(e,t,n){return e.Ne(t,n)<=0?t:n}function xfn(e,t){return l(B1(e.b,t),143)}function kfn(e,t){return l(B1(e.c,t),233)}function uae(e){return l(jt(e.a,e.b),294)}function _rt(e){return new lt(e.c,e.d+e.a)}function Art(e){return nr(e),e?1231:1237}function Lrt(e){return Sh(),ont(l(e,203))}function py(){py=U,q_e=un((mh(),Cv))}function Efn(e,t){t.a?_En(e,t):tae(e.a,t.b)}function AO(e,t,n){++e.j,e.tj(),Noe(e,t,n)}function Mrt(e,t,n){++e.j,e.qj(t,e.Zi(t,n))}function Drt(e,t,n){var r;r=e.fd(t),r.Rb(n)}function Wye(e,t,n){return n=Nh(e,t,6,n),n}function Yye(e,t,n){return n=Nh(e,t,3,n),n}function Xye(e,t,n){return n=Nh(e,t,9,n),n}function vd(e,t){return UO(t,yEe),e.f=t,e}function Qye(e,t){return(t&Ii)%e.d.length}function Irt(e,t,n){return Mke(e.c,e.b,t,n)}function Ort(e,t){this.c=e,Lw.call(this,t)}function Nrt(e,t){this.a=e,vQe.call(this,t)}function LO(e,t){this.a=e,vQe.call(this,t)}function vs(e,t){Ui.call(this,e),this.a=t}function Jye(e,t){xwe.call(this,e),this.a=t}function lae(e,t){xwe.call(this,e),this.a=t}function Tfn(e){I8e.call(this,0,0),this.f=e}function Prt(e,t,n){return e.a+=If(t,0,n),e}function MO(e){return!e.a&&(e.a=new ge),e.a}function Zye(e,t){var n;return n=e.e,e.e=t,n}function e4e(e,t){var n;return n=t,!!e.Fe(n)}function Cfn(e,t){return Hn(),e==t?0:e?1:-1}function by(e,t){e.a.bd(e.b,t),++e.b,e.c=-1}function DO(e){e.b?DO(e.b):e.f.c.zc(e.e,e.d)}function Brt(e){Nl(e.e),e.d.b=e.d,e.d.a=e.d}function Sfn(e,t,n){Am(),Eie(e,t.Ve(e.a,n))}function t4e(e,t,n){return Q8(e,l(t,22),n)}function c0(e,t){return Vz(new Array(t),e)}function _fn(e){return Yr(ub(e,32))^Yr(e)}function hae(e){return String.fromCharCode(e)}function Afn(e){return e==null?null:e.message}function Lfn(e,t,n){return e.apply(t,n)}function Mfn(e,t){var n;n=e[lhe],n.call(e,t)}function Dfn(e,t){var n;n=e[lhe],n.call(e,t)}function Ifn(e,t){return sO(),!bE(t.d.i,e)}function n4e(e,t,n,r){sH.call(this,e,t,n,r)}function Frt(){Vq.call(this),this.a=new qa}function r4e(){this.n=new qa,this.o=new qa}function Rrt(){this.b=new qa,this.c=new bt}function jrt(){this.a=new bt,this.b=new bt}function $rt(){this.a=new bm,this.b=new BQe}function i4e(){this.b=new e2,this.a=new e2}function zrt(){this.b=new Ks,this.a=new Ks}function qrt(){this.b=new Pr,this.a=new Pr}function Hrt(){this.b=new dZe,this.a=new CS}function Vrt(){this.a=new Wre,this.b=new Aee}function Urt(){this.a=new bt,this.d=new bt}function Vq(){this.n=new A8,this.i=new $8}function Grt(e){this.a=(Mh(e,Yy),new Bu(e))}function Krt(e){this.a=(Mh(e,Yy),new Bu(e))}function Ofn(e){return e<100?null:new nb(e)}function Nfn(e,t){return e.n.a=(nr(t),t+10)}function Pfn(e,t){return e.n.a=(nr(t),t+10)}function Bfn(e,t){return t==e||jE(_U(t),e)}function Wrt(e,t){return ki(e.a,t,"")==null}function Ffn(e,t){var n;return n=t.qi(e.a),n}function Oi(e,t){return e.a+=t.a,e.b+=t.b,e}function ma(e,t){return e.a-=t.a,e.b-=t.b,e}function Rfn(e){return ay(e.j.c,0),e.a=-1,e}function s4e(e,t,n){return n=Nh(e,t,11,n),n}function jfn(e,t,n){n!=null&&wV(t,pue(e,n))}function $fn(e,t,n){n!=null&&yV(t,pue(e,n))}function V8(e,t,n,r){nt.call(this,e,t,n,r)}function a4e(e,t,n,r){nt.call(this,e,t,n,r)}function Yrt(e,t,n,r){a4e.call(this,e,t,n,r)}function Xrt(e,t,n,r){pH.call(this,e,t,n,r)}function fae(e,t,n,r){pH.call(this,e,t,n,r)}function o4e(e,t,n,r){pH.call(this,e,t,n,r)}function Qrt(e,t,n,r){fae.call(this,e,t,n,r)}function c4e(e,t,n,r){fae.call(this,e,t,n,r)}function Ln(e,t,n,r){o4e.call(this,e,t,n,r)}function Jrt(e,t,n,r){c4e.call(this,e,t,n,r)}function Zrt(e,t,n,r){a5e.call(this,e,t,n,r)}function my(e,t){tc.call(this,CL+e+av+t)}function u4e(e,t){return e.jk().wi().ri(e,t)}function l4e(e,t){return e.jk().wi().ti(e,t)}function eit(e,t){return nr(e),qe(e)===qe(t)}function vn(e,t){return nr(e),qe(e)===qe(t)}function zfn(e,t){return e.b.Bd(new ket(e,t))}function qfn(e,t){return e.b.Bd(new Eet(e,t))}function tit(e,t){return e.b.Bd(new Tet(e,t))}function Hfn(e,t){return e.e=l(e.d.Kb(t),159)}function h4e(e,t,n){return e.lastIndexOf(t,n)}function Vfn(e,t,n){return Yi(e[t.a],e[n.a])}function Ufn(e,t){return rt(t,(Nt(),TB),e)}function Gfn(e,t){return ru(t.a.d.p,e.a.d.p)}function Kfn(e,t){return ru(e.a.d.p,t.a.d.p)}function Wfn(e,t){return Yi(e.c-e.s,t.c-t.s)}function Yfn(e,t){return Yi(e.b.e.a,t.b.e.a)}function Xfn(e,t){return Yi(e.c.e.a,t.c.e.a)}function nit(e){return e.c?gc(e.c.a,e,0):-1}function U8(e){return e==Tv||e==Tg||e==Mu}function f4e(e,t){this.c=e,jae.call(this,e,t)}function rit(e,t,n){this.a=e,Nye.call(this,t,n)}function iit(e){this.c=e,Dq.call(this,EP,0)}function sit(e,t,n){this.c=t,this.b=n,this.a=e}function IO(e){jk(),this.d=e,this.a=new z5}function ait(e){wd(),this.a=(Cn(),new Ek(e))}function Qfn(e,t){Ug(e.f)?ZEn(e,t):Mxn(e,t)}function oit(e,t){ldn.call(this,e,e.length,t)}function Jfn(e,t){G1||t&&(e.d=t)}function cit(e,t){return De(t,15)&&Bbt(e.c,t)}function Zfn(e,t,n){return l(e.c,71).Wk(t,n)}function Uq(e,t,n){return l(e.c,71).Xk(t,n)}function e0n(e,t,n){return ufn(e,l(t,343),n)}function d4e(e,t,n){return lfn(e,l(t,343),n)}function t0n(e,t,n){return Lgt(e,l(t,343),n)}function uit(e,t,n){return Hxn(e,l(t,343),n)}function H_(e,t){return t==null?null:Oy(e.b,t)}function g4e(e){return fy(e)?(nr(e),e):e.ue()}function Gq(e){return!isNaN(e)&&!isFinite(e)}function dae(e){knt(this),Ch(this),Ka(this,e)}function Ol(e){Yse(this),M4e(this.c,0,e.Pc())}function Zh(e,t,n){this.a=e,this.b=t,this.c=n}function lit(e,t,n){this.a=e,this.b=t,this.c=n}function hit(e,t,n){this.d=e,this.b=n,this.a=t}function fit(e){this.a=e,Vg(),Zc(Date.now())}function dit(e){ph(e.a),L6e(e.c,e.b),e.b=null}function gae(){gae=U,p_e=new Et,_6t=new Gt}function git(){git=U,M_t=We(wa,Rn,1,0,5,1)}function pit(){pit=U,W_t=We(wa,Rn,1,0,5,1)}function p4e(){p4e=U,Y_t=We(wa,Rn,1,0,5,1)}function wd(){wd=U,new Twe((Cn(),Cn(),_o))}function n0n(e){return rE(),Gr((xlt(),M6t),e)}function r0n(e){return Fl(),Gr((hlt(),B6t),e)}function i0n(e){return ZV(),Gr((Xct(),q6t),e)}function s0n(e){return aV(),Gr((Qct(),H6t),e)}function a0n(e){return PU(),Gr((Xft(),V6t),e)}function o0n(e){return t1(),Gr((ult(),K6t),e)}function c0n(e){return Bl(),Gr((clt(),Y6t),e)}function u0n(e){return ol(),Gr((llt(),Q6t),e)}function l0n(e){return YU(),Gr((Gtt(),y7t),e)}function h0n(e){return Pw(),Gr((Elt(),k7t),e)}function f0n(e){return bx(),Gr((Clt(),T7t),e)}function d0n(e){return NA(),Gr((Tlt(),_7t),e)}function g0n(e){return Zz(),Gr((kct(),A7t),e)}function p0n(e){return oV(),Gr((Jct(),U7t),e)}function b0n(e){return lA(),Gr((flt(),m8t),e)}function m0n(e){return uo(),Gr((aht(),x8t),e)}function v0n(e){return wE(),Gr((_lt(),S8t),e)}function w0n(e){return Km(),Gr((Slt(),I8t),e)}function b4e(e,t){if(!e)throw ue(new Yn(t))}function Rk(e){if(!e)throw ue(new nc(Jke))}function pae(e,t){if(e!=t)throw ue(new Xh)}function bit(e,t,n){this.a=e,this.b=t,this.c=n}function m4e(e,t,n){this.a=e,this.b=t,this.c=n}function mit(e,t,n){this.a=e,this.b=t,this.c=n}function Kq(e,t,n){this.b=e,this.a=t,this.c=n}function v4e(e,t,n){this.b=e,this.c=t,this.a=n}function w4e(e,t,n){this.a=e,this.b=t,this.c=n}function Wq(e,t,n){this.e=t,this.b=e,this.d=n}function vit(e,t,n){this.b=e,this.a=t,this.c=n}function y0n(e,t,n){return Am(),e.a.Yd(t,n),t}function bae(e){var t;return t=new Ml,t.e=e,t}function y4e(e){var t;return t=new zQe,t.b=e,t}function OO(){OO=U,CK=new pZ,SK=new dj}function Yq(){Yq=U,K8t=new SZ,G8t=new bS}function u0(){u0=U,J8t=new iee,Z8t=new see}function x0n(e){return Ow(),Gr((Hut(),uxt),e)}function k0n(e){return vo(),Gr((Ktt(),q8t),e)}function E0n(e){return IV(),Gr((Llt(),U8t),e)}function T0n(e){return R1(),Gr((Alt(),nxt),e)}function C0n(e){return Ry(),Gr((oht(),ixt),e)}function S0n(e){return OU(),Gr((Pft(),lxt),e)}function _0n(e){return yx(),Gr((Iht(),hxt),e)}function A0n(e){return JH(),Gr((sut(),fxt),e)}function L0n(e){return dA(),Gr((zut(),dxt),e)}function M0n(e){return pV(),Gr((qut(),gxt),e)}function D0n(e){return l2(),Gr((cht(),pxt),e)}function I0n(e){return pN(),Gr((tut(),bxt),e)}function O0n(e){return zE(),Gr((Pht(),kxt),e)}function N0n(e){return Ho(),Gr((f0t(),Ext),e)}function P0n(e){return vE(),Gr((Uut(),Txt),e)}function B0n(e){return ep(),Gr((Gut(),Sxt),e)}function F0n(e){return zH(),Gr((eut(),_xt),e)}function R0n(e){return WN(),Gr((Nht(),xxt),e)}function j0n(e){return Vm(),Gr((Vut(),vxt),e)}function $0n(e){return yU(),Gr((Oht(),wxt),e)}function z0n(e){return cN(),Gr((nut(),yxt),e)}function q0n(e){return hf(),Gr((lht(),Axt),e)}function H0n(e){return p2(),Gr((Kft(),Jkt),e)}function V0n(e){return EA(),Gr((Kut(),Zkt),e)}function U0n(e){return By(),Gr((Mlt(),eEt),e)}function G0n(e){return OA(),Gr((uht(),tEt),e)}function K0n(e){return Nf(),Gr((d0t(),nEt),e)}function W0n(e){return Ed(),Gr((Dlt(),rEt),e)}function Y0n(e){return dN(),Gr((rut(),iEt),e)}function X0n(e){return qo(),Gr((Xut(),aEt),e)}function Q0n(e){return LV(),Gr((Wut(),oEt),e)}function J0n(e){return yA(),Gr((Yut(),cEt),e)}function Z0n(e){return SE(),Gr((Qut(),uEt),e)}function e1n(e){return gV(),Gr((Jut(),lEt),e)}function t1n(e){return OV(),Gr((Zut(),hEt),e)}function n1n(e){return Iw(),Gr((olt(),_Et),e)}function r1n(e){return oA(),Gr((iut(),IEt),e)}function i1n(e){return xd(),Gr((cut(),jEt),e)}function s1n(e){return D1(),Gr((uut(),zEt),e)}function a1n(e){return J0(),Gr((lut(),nTt),e)}function o1n(e){return Sw(),Gr((hut(),uTt),e)}function c1n(e){return wx(),Gr((Rlt(),lTt),e)}function u1n(e){return WA(),Gr((Wtt(),hTt),e)}function l1n(e){return xA(),Gr((elt(),fTt),e)}function h1n(e){return kA(),Gr((Flt(),PTt),e)}function f1n(e){return RH(),Gr((aut(),BTt),e)}function d1n(e){return kV(),Gr((out(),zTt),e)}function g1n(e){return bU(),Gr((hht(),HTt),e)}function p1n(e){return LN(),Gr((tlt(),UTt),e)}function b1n(e){return eV(),Gr((fut(),VTt),e)}function m1n(e){return uU(),Gr((Blt(),hCt),e)}function v1n(e){return AV(),Gr((nlt(),fCt),e)}function w1n(e){return WV(),Gr((rlt(),dCt),e)}function y1n(e){return sU(),Gr((ilt(),pCt),e)}function x1n(e){return qV(),Gr((slt(),vCt),e)}function k1n(e){return GH(),Gr((dut(),jCt),e)}function E1n(e){return dE(),Gr((Zct(),z8t),e)}function T1n(e){return Zn(),Gr((Bht(),B8t),e)}function C1n(e){return tV(),Gr((alt(),$Ct),e)}function S1n(e){return fce(),Gr((gut(),zCt),e)}function _1n(e){return VA(),Gr((fht(),HCt),e)}function A1n(e){return nq(),Gr((Mct(),UCt),e)}function L1n(e){return PN(),Gr((glt(),VCt),e)}function M1n(e){return rq(),Gr((Dct(),KCt),e)}function D1n(e){return rN(),Gr((put(),WCt),e)}function I1n(e){return XN(),Gr((dht(),YCt),e)}function O1n(e){return b_(),Gr((Ict(),hSt),e)}function N1n(e){return CN(),Gr((but(),fSt),e)}function P1n(e){return r1(),Gr((pht(),vSt),e)}function B1n(e){return g2(),Gr((Oft(),ySt),e)}function F1n(e){return og(),Gr((Fht(),xSt),e)}function R1n(e){return Ym(),Gr((Rht(),_St),e)}function j1n(e){return Js(),Gr((ght(),GSt),e)}function $1n(e){return F1(),Gr((plt(),KSt),e)}function z1n(e){return ip(),Gr((jlt(),WSt),e)}function q1n(e){return vU(),Gr((jht(),YSt),e)}function H1n(e){return rp(),Gr((dlt(),QSt),e)}function V1n(e){return Ih(),Gr(($lt(),ZSt),e)}function U1n(e){return qy(),Gr((Yft(),e_t),e)}function G1n(e){return t6(),Gr((bht(),t_t),e)}function K1n(e){return Ra(),Gr(($ht(),n_t),e)}function W1n(e){return Rl(),Gr((zht(),r_t),e)}function Y1n(e){return Ct(),Gr((mht(),i_t),e)}function X1n(e){return mh(),Gr((zlt(),u_t),e)}function Q1n(e){return Zl(),Gr((Wft(),l_t),e)}function J1n(e){return dx(),Gr((blt(),h_t),e)}function Z1n(e,t){return nr(e),e+(nr(t),t)}function edn(e){return mae(),Gr((mut(),f_t),e)}function tdn(e){return VV(),Gr((qlt(),d_t),e)}function ndn(e){return NV(),Gr((Hlt(),b_t),e)}function jk(){jk=U,$De=(Ct(),er),DW=ar}function mae(){mae=U,rPe=new Wit,iPe=new Ost}function rdn(e){return!e.e&&(e.e=new bt),e.e}function vae(e,t){this.c=e,this.a=t,this.b=t-e}function wit(e,t,n){this.a=e,this.b=t,this.c=n}function wae(e,t,n){this.a=e,this.b=t,this.c=n}function x4e(e,t,n){this.a=e,this.b=t,this.c=n}function k4e(e,t,n){this.a=e,this.b=t,this.c=n}function yit(e,t,n){this.a=e,this.b=t,this.c=n}function xit(e,t,n){this.a=e,this.b=t,this.c=n}function Xp(e,t,n){this.e=e,this.a=t,this.c=n}function kit(e,t,n){Jh(),$5e.call(this,e,t,n)}function yae(e,t,n){Jh(),E5e.call(this,e,t,n)}function E4e(e,t,n){Jh(),E5e.call(this,e,t,n)}function T4e(e,t,n){Jh(),E5e.call(this,e,t,n)}function Eit(e,t,n){Jh(),yae.call(this,e,t,n)}function C4e(e,t,n){Jh(),yae.call(this,e,t,n)}function Tit(e,t,n){Jh(),C4e.call(this,e,t,n)}function Cit(e,t,n){Jh(),E4e.call(this,e,t,n)}function Sit(e,t,n){Jh(),T4e.call(this,e,t,n)}function xae(e){sH.call(this,e.d,e.c,e.a,e.b)}function S4e(e){sH.call(this,e.d,e.c,e.a,e.b)}function _4e(e){this.d=e,Mr(this),this.b=ngn(e.d)}function idn(e){return HE(),Gr((Nft(),L_t),e)}function NO(e,t){return Xr(e),Xr(t),new IZe(e,t)}function G8(e,t){return Xr(e),Xr(t),new jit(e,t)}function sdn(e,t){return Xr(e),Xr(t),new $it(e,t)}function adn(e,t){return Xr(e),Xr(t),new zZe(e,t)}function kae(e){return mr(e.b!=0),af(e,e.a.a)}function odn(e){return mr(e.b!=0),af(e,e.c.b)}function cdn(e){return!e.c&&(e.c=new Xd),e.c}function $k(e){var t;return t=new bt,Goe(t,e),t}function udn(e){var t;return t=new Ks,Goe(t,e),t}function _it(e){var t;return t=new Lwe,sce(t,e),t}function PO(e){var t;return t=new os,sce(t,e),t}function l(e,t){return V_(e==null||iue(e,t)),e}function ldn(e,t,n){Sst.call(this,t,n),this.a=e}function Ait(e,t){this.c=e,this.b=t,this.a=!1}function Lit(){this.a=";,;",this.b="",this.c=""}function Mit(e,t,n){this.b=e,ztt.call(this,t,n)}function A4e(e,t,n){this.c=e,cq.call(this,t,n)}function L4e(e,t,n){Ik.call(this,e,t),this.b=n}function M4e(e,t,n){k9e(n,0,e,t,n.length,!1)}function tg(e,t,n,r,a){e.b=t,e.c=n,e.d=r,e.a=a}function D4e(e,t,n,r,a){e.d=t,e.c=n,e.a=r,e.b=a}function hdn(e,t){t&&(e.b=t,e.a=(fb(t),t.a))}function BO(e,t){if(!e)throw ue(new Yn(t))}function K8(e,t){if(!e)throw ue(new nc(t))}function I4e(e,t){if(!e)throw ue(new BJe(t))}function fdn(e,t){return eq(),ru(e.d.p,t.d.p)}function ddn(e,t){return tp(),Yi(e.e.b,t.e.b)}function gdn(e,t){return tp(),Yi(e.e.a,t.e.a)}function pdn(e,t){return ru(Uit(e.d),Uit(t.d))}function Xq(e,t){return t&&yH(e,t.d)?t:null}function bdn(e,t){return t==(Ct(),er)?e.c:e.d}function O4e(e){return mb(pgn(wc(e)?Mf(e):e))}function mdn(e){return new lt(e.c+e.b,e.d+e.a)}function Dit(e){return e!=null&&!Hce(e,$M,zM)}function vdn(e,t){return(u1t(e)<<4|u1t(t))&Zs}function Iit(e,t,n,r,a){e.c=t,e.d=n,e.b=r,e.a=a}function N4e(e){var t,n;t=e.b,n=e.c,e.b=n,e.c=t}function P4e(e){var t,n;n=e.d,t=e.a,e.d=t,e.a=n}function wdn(e,t){var n;return n=e.c,d7e(e,t),n}function B4e(e,t){return t<0?e.g=-1:e.g=t,e}function Qq(e,t){return _wn(e),e.a*=t,e.b*=t,e}function Oit(e,t,n){_ht.call(this,t,n),this.d=e}function FO(e,t,n){tye.call(this,e,t),this.c=n}function Jq(e,t,n){tye.call(this,e,t),this.c=n}function F4e(e){p4e(),m5.call(this),this.ci(e)}function Nit(){eE(),$gn.call(this,(ib(),Gf))}function Pit(e){return Di(),new ng(0,e)}function Bit(){Bit=U,spe=(Cn(),new Da(c0e))}function Zq(){Zq=U,new W8e((Gie(),y0e),(Uie(),w0e))}function Fit(){Fit=U,t_e=We(ro,dt,17,256,0,1)}function Rit(){this.b=ze(Ge(It((b0(),Z0e))))}function Eae(e){this.b=e,this.a=Mm(this.b.a).Od()}function jit(e,t){this.b=e,this.a=t,GS.call(this)}function $it(e,t){this.a=e,this.b=t,GS.call(this)}function zit(e,t,n){this.a=e,N5.call(this,t,n)}function qit(e,t,n){this.a=e,N5.call(this,t,n)}function zk(e,t,n){var r;r=new yy(n),e1(e,t,r)}function R4e(e,t,n){var r;return r=e[t],e[t]=n,r}function eH(e){var t;return t=e.slice(),joe(t,e)}function tH(e){var t;return t=e.n,e.a.b+t.d+t.a}function Hit(e){var t;return t=e.n,e.e.b+t.d+t.a}function j4e(e){var t;return t=e.n,e.e.a+t.b+t.c}function $4e(e){e.a.b=e.b,e.b.a=e.a,e.a=e.b=null}function ui(e,t){return Cs(e,t,e.c.b,e.c),!0}function ydn(e){return e.a?e.a:Qae(e)}function xdn(e){return tx(),cg(e)==ds(Eb(e))}function kdn(e){return tx(),Eb(e)==ds(cg(e))}function gw(e,t){return RA(e,new Ik(t.a,t.b))}function Edn(e,t){return kH(),fue(e,t),new hat(e,t)}function Tdn(e,t){return e.c=t)throw ue(new Bwe)}function vy(e,t){return ON(e,(nr(t),new xo(t)))}function Y8(e,t){return ON(e,(nr(t),new lh(t)))}function Ast(e,t,n){return XIn(e,l(t,12),l(n,12))}function Lst(e){return kl(),l(e,12).g.c.length!=0}function Mst(e){return kl(),l(e,12).e.c.length!=0}function cgn(e,t){return lx(),Yi(t.a.o.a,e.a.o.a)}function ugn(e,t){t.Bb&eu&&!e.a.o&&(e.a.o=t)}function lgn(e,t){t.Ug("General 'Rotator",1),TDn(e)}function hgn(e,t,n){t.qf(n,ze(Ge(cr(e.b,n)))*e.a)}function Dst(e,t,n){return h6(),gE(e,t)&&gE(e,n)}function W_(e){return Rl(),!e.Hc(vp)&&!e.Hc(Yb)}function fgn(e){return e.e?_6e(e.e):null}function Y_(e){return wc(e)?""+e:Pbt(e)}function s5e(e){var t;for(t=e;t.f;)t=t.f;return t}function dgn(e,t,n){return Ts(t,0,U4e(t[0],n[0])),t}function Qp(e,t,n,r){var a;a=e.i,a.i=t,a.a=n,a.b=r}function nt(e,t,n,r){Ys.call(this,e,t,n),this.b=r}function _a(e,t,n,r,a){Foe.call(this,e,t,n,r,a,-1)}function X_(e,t,n,r,a){sN.call(this,e,t,n,r,a,-1)}function pH(e,t,n,r){FO.call(this,e,t,n),this.b=r}function Ist(e){Ltt.call(this,e,!1),this.a=!1}function Ost(){ctt.call(this,"LOOKAHEAD_LAYOUT",1)}function Nst(e){this.b=e,q8.call(this,e),jnt(this)}function Pst(e){this.b=e,CO.call(this,e),$nt(this)}function wy(e,t,n){this.a=e,V8.call(this,t,n,5,6)}function a5e(e,t,n,r){this.b=e,Ys.call(this,t,n,r)}function Bst(e,t){this.b=e,qg.call(this,e.b),this.a=t}function Fst(e){this.a=ydt(e.a),this.b=new Ol(e.b)}function o5e(e,t){ww(),Vun.call(this,e,RV(new Il(t)))}function bH(e,t){return Di(),new k5e(e,t,0)}function Bae(e,t){return Di(),new k5e(6,e,t)}function Za(e,t){for(nr(t);e.Ob();)t.Cd(e.Pb())}function Hu(e,t){return Ia(t)?soe(e,t):!!zo(e.f,t)}function Fae(e,t){return t.Vh()?yb(e.b,l(t,54)):t}function ggn(e,t){return vn(e.substr(0,t.length),t)}function rg(e){return new hr(new Aye(e.a.length,e.a))}function mH(e){return new lt(e.c+e.b/2,e.d+e.a/2)}function pgn(e){return qu(~e.l&eh,~e.m&eh,~e.h&hp)}function Rae(e){return typeof e===wP||typeof e===Ole}function Nl(e){e.f=new rnt(e),e.i=new int(e),++e.g}function Rst(e){if(!e)throw ue(new _c);return e.d}function X8(e){var t;return t=wA(e),mr(t!=null),t}function bgn(e){var t;return t=I4n(e),mr(t!=null),t}function Hk(e,t){var n;return n=e.a.gc(),k6e(t,n),n-t}function na(e,t){var n;return n=e.a.zc(t,e),n==null}function jO(e,t){return e.a.zc(t,(Hn(),Pb))==null}function c5e(e){return new bn(null,xgn(e,e.length))}function u5e(e,t,n){return svt(e,l(t,42),l(n,176))}function Q8(e,t,n){return d0(e.a,t),R4e(e.b,t.g,n)}function mgn(e,t,n){qk(n,e.a.c.length),rf(e.a,n,t)}function He(e,t,n,r){B0t(t,n,e.length),vgn(e,t,n,r)}function vgn(e,t,n,r){var a;for(a=t;a0?b.Math.log(e/t):-100}function $st(e,t){return iu(e,t)<0?-1:iu(e,t)>0?1:0}function $O(e,t){Dnt(e,De(t,160)?t:l(t,2036).Rl())}function d5e(e,t){if(e==null)throw ue(new D8(t))}function xgn(e,t){return Ewn(t,e.length),new Kit(e,t)}function g5e(e,t){return t?Ka(e,t):!1}function kgn(){return $z(),he(le(a6t,1),it,549,0,[E0e])}function J_(e){return e.e==0?e:new Im(-e.e,e.d,e.a)}function Egn(e,t){return Yi(e.c.c+e.c.b,t.c.c+t.c.b)}function zO(e,t){Cs(e.d,t,e.b.b,e.b),++e.a,e.c=null}function zst(e,t){return e.c?zst(e.c,t):vt(e.b,t),e}function Tgn(e,t,n){var r;return r=_y(e,t),xoe(e,t,n),r}function qst(e,t,n){var r;for(r=0;r=e.g}function Ts(e,t,n){return pfn(n==null||lAn(e,n)),e[t]=n}function w5e(e,t){return Xn(t,e.length+1),e.substr(t)}function Wae(e,t){for(nr(t);e.c=e?new b3e:Kwn(e-1)}function eo(e){return!e.a&&e.c?e.c.b:e.a}function T5e(e){return De(e,616)?e:new oot(e)}function fb(e){e.c?fb(e.c):(xb(e),e.d=!0)}function tA(e){e.c?e.c.$e():(e.d=!0,hCn(e))}function cat(e){e.b=!1,e.c=!1,e.d=!1,e.a=!1}function uat(e){var t,n;return t=e.c.i.c,n=e.d.i.c,t==n}function Hgn(e,t){var n;n=e.Ih(t),n>=0?e.ki(n):d9e(e,t)}function lat(e,t){e.c<0||e.b.b0;)e=e<<1|(e<0?1:0);return e}function vat(e,t){var n;return n=new yu(e),$n(t.c,n),n}function wat(e,t){e.u.Hc((Rl(),vp))&&Wkn(e,t),fvn(e,t)}function Jc(e,t){return qe(e)===qe(t)||e!=null&&Pi(e,t)}function Qo(e,t){return Aae(e.a,t)?e.b[l(t,22).g]:null}function npn(){return Zz(),he(le(U_e,1),it,489,0,[G0e])}function rpn(){return nq(),he(le(wOe,1),it,490,0,[bge])}function ipn(){return rq(),he(le(GCt,1),it,558,0,[mge])}function spn(){return b_(),he(le($Oe,1),it,539,0,[qB])}function EH(e){return!e.n&&(e.n=new nt(ec,e,1,7)),e.n}function Xae(e){return!e.c&&(e.c=new nt(Hl,e,9,9)),e.c}function A5e(e){return!e.c&&(e.c=new Ln(_r,e,5,8)),e.c}function apn(e){return!e.b&&(e.b=new Ln(_r,e,4,7)),e.b}function qO(e){return e.j.c.length=0,M5e(e.c),Rfn(e.a),e}function Wk(e){return e.e==ET&&hn(e,e6n(e.g,e.b)),e.e}function HO(e){return e.f==ET&&Dn(e,U7n(e.g,e.b)),e.f}function Ei(e,t,n,r){return qft(e,t,n,!1),jV(e,r),e}function yat(e,t){this.b=e,jae.call(this,e,t),jnt(this)}function xat(e,t){this.b=e,f4e.call(this,e,t),$nt(this)}function nA(e){this.d=e,this.a=this.d.b,this.b=this.d.c}function L5e(e,t){this.b=e,this.c=t,this.a=new P8(this.b)}function co(e,t){return Xn(t,e.length),e.charCodeAt(t)}function opn(e,t){b8e(e,ze(np(t,"x")),ze(np(t,"y")))}function cpn(e,t){b8e(e,ze(np(t,"x")),ze(np(t,"y")))}function Fi(e,t){return xb(e),new bn(e,new $6e(t,e.a))}function fc(e,t){return xb(e),new bn(e,new C6e(t,e.a))}function xy(e,t){return xb(e),new Vye(e,new Mut(t,e.a))}function TH(e,t){return xb(e),new Uye(e,new Dut(t,e.a))}function upn(e,t){return new Uat(l(Xr(e),50),l(Xr(t),50))}function lpn(e,t){return Yi(e.d.c+e.d.b/2,t.d.c+t.d.b/2)}function kat(e,t,n){n.a?Gu(e,t.b-e.f/2):Uu(e,t.a-e.g/2)}function hpn(e,t){return Yi(e.g.c+e.g.b/2,t.g.c+t.g.b/2)}function fpn(e,t){return w3e(),Yi((nr(e),e),(nr(t),t))}function dpn(e){return e!=null&&nO(EY,e.toLowerCase())}function M5e(e){var t;for(t=e.Kc();t.Ob();)t.Pb(),t.Qb()}function V5(e){var t;return t=e.b,!t&&(e.b=t=new mie(e)),t}function Qae(e){var t;return t=Qwn(e),t||null}function Eat(e,t){var n,r;return n=e/t,r=ua(n),n>r&&++r,r}function gpn(e,t,n){var r;r=l(e.d.Kb(n),159),r&&r.Nb(t)}function ppn(e,t,n){mLn(e.a,n),W3n(n),REn(e.b,n),RLn(t,n)}function CH(e,t,n,r){this.a=e,this.c=t,this.b=n,this.d=r}function D5e(e,t,n,r){this.c=e,this.b=t,this.a=n,this.d=r}function Tat(e,t,n,r){this.c=e,this.b=t,this.d=n,this.a=r}function ef(e,t,n,r){this.c=e,this.d=t,this.b=n,this.a=r}function Cat(e,t,n,r){this.a=e,this.d=t,this.c=n,this.b=r}function Jae(e,t,n,r){this.a=e,this.e=t,this.d=n,this.c=r}function Sat(e,t,n,r){this.a=e,this.c=t,this.d=n,this.b=r}function Zae(e,t,n){this.a=iEe,this.d=e,this.b=t,this.c=n}function Z8(e,t,n,r){Ur.call(this,e,t),this.a=n,this.b=r}function _at(e,t){this.d=(nr(e),e),this.a=16449,this.c=t}function Aat(e){this.a=new bt,this.e=We(Vr,dt,53,e,0,2)}function bpn(e){e.Ug("No crossing minimization",1),e.Vg()}function Lat(){Ac.call(this,"There is no more element.")}function Mat(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function Dat(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function Om(e,t,n,r){this.e=e,this.a=t,this.c=n,this.d=r}function Iat(e,t,n,r){this.a=e,this.c=t,this.d=n,this.b=r}function Oat(e,t,n,r){Jh(),Iut.call(this,t,n,r),this.a=e}function Nat(e,t,n,r){Jh(),Iut.call(this,t,n,r),this.a=e}function eoe(e,t,n){var r,a;return r=Vke(e),a=t.ti(n,r),a}function Kg(e){var t,n;return n=(t=new Qv,t),sE(n,e),n}function toe(e){var t,n;return n=(t=new Qv,t),Kxe(n,e),n}function mpn(e,t){var n;return n=cr(e.f,t),S7e(t,n),null}function Pat(e){return!e.b&&(e.b=new nt(js,e,12,3)),e.b}function Bat(e){return V_(e==null||Rae(e)&&e.Tm!==xe),e}function SH(e){return e.n&&(e.e!==Fwt&&e.je(),e.j=null),e}function Yk(e){if(Ql(e.d),e.d.d!=e.c)throw ue(new Xh)}function I5e(e){return mr(e.b0&&ggt(this)}function Fat(e,t){this.a=e,bfn.call(this,e,l(e.d,15).fd(t))}function vpn(e,t){return Yi(wl(e)*gh(e),wl(t)*gh(t))}function wpn(e,t){return Yi(wl(e)*gh(e),wl(t)*gh(t))}function ypn(e){return qw(e)&&Rt(Bt(at(e,(Nt(),gv))))}function xpn(e,t){return xn(e,l(Q(t,(Nt(),HT)),17),t)}function kpn(e,t){return l(Q(e,(ft(),Wx)),15).Fc(t),t}function O5e(e,t){return e.b=t.b,e.c=t.c,e.d=t.d,e.a=t.a,e}function Rat(e,t,n,r){this.b=e,this.c=r,Dq.call(this,t,n)}function Epn(e,t,n){e.i=0,e.e=0,t!=n&&x0t(e,t,n)}function Tpn(e,t,n){e.i=0,e.e=0,t!=n&&k0t(e,t,n)}function Cpn(e,t,n){return p_(),J4n(l(cr(e.e,t),529),n)}function ex(e){var t;return t=e.f,t||(e.f=new Lk(e,e.c))}function jat(e,t){return e6(e.j,t.s,t.c)+e6(t.e,e.s,e.c)}function $at(e,t){e.e&&!e.e.a&&(CQe(e.e,t),$at(e.e,t))}function zat(e,t){e.d&&!e.d.a&&(CQe(e.d,t),zat(e.d,t))}function Spn(e,t){return-Yi(wl(e)*gh(e),wl(t)*gh(t))}function _pn(e){return l(e.ld(),149).Pg()+":"+xc(e.md())}function qat(){Nue(this,new fz),this.wb=(lb(),Vn),Sk()}function Hat(e){this.b=new bt,ra(this.b,this.b),this.a=e}function N5e(e,t){new os,this.a=new bl,this.b=e,this.c=t}function Ew(){Ew=U,d_e=new Ke,D0e=new Ke,g_e=new Ft}function Cn(){Cn=U,_o=new je,mg=new Se,hK=new Ce}function P5e(){P5e=U,j6t=new wo,z6t=new X4e,$6t=new _s}function tx(){tx=U,wK=new bt,X0e=new Pr,Y0e=new bt}function _H(e,t){if(e==null)throw ue(new D8(t));return e}function AH(e){return!e.a&&(e.a=new nt(Ai,e,10,11)),e.a}function qi(e){return!e.q&&(e.q=new nt(Uf,e,11,10)),e.q}function tt(e){return!e.s&&(e.s=new nt(dl,e,21,17)),e.s}function Apn(e){return Xr(e),Mdt(new hr(dr(e.a.Kc(),new j)))}function Lpn(e,t){return bh(e),bh(t),PJe(l(e,22),l(t,22))}function Nm(e,t,n){var r,a;r=g4e(n),a=new vk(r),e1(e,t,a)}function roe(e,t,n,r,a,o){sN.call(this,e,t,n,r,a,o?-2:-1)}function Vat(e,t,n,r){tye.call(this,t,n),this.b=e,this.a=r}function Uat(e,t){Xcn.call(this,new Pae(e)),this.a=e,this.b=t}function B5e(e){this.b=e,this.c=e,e.e=null,e.c=null,this.a=1}function Mpn(e){u0();var t;t=l(e.g,10),t.n.a=e.d.c+t.d.b}function Xk(){Xk=U;var e,t;t=!F5n(),e=new se,S0e=t?new ne:e}function ioe(e){return Cn(),De(e,59)?new ese(e):new jq(e)}function LH(e){return De(e,16)?new U_(l(e,16)):udn(e.Kc())}function Dpn(e){return new qnt(e,e.e.Rd().gc()*e.c.Rd().gc())}function Ipn(e){return new Hnt(e,e.e.Rd().gc()*e.c.Rd().gc())}function F5e(e){return e&&e.hashCode?e.hashCode():fw(e)}function soe(e,t){return t==null?!!zo(e.f,null):Wdn(e.i,t)}function Opn(e,t){var n;return n=wye(e.a,t),n&&(t.d=null),n}function Gat(e,t,n){return e.f?e.f.ef(t,n):!1}function VO(e,t,n,r){Ts(e.c[t.g],n.g,r),Ts(e.c[n.g],t.g,r)}function aoe(e,t,n,r){Ts(e.c[t.g],t.g,n),Ts(e.b[t.g],t.g,r)}function Npn(e,t,n){return ze(Ge(n.a))<=e&&ze(Ge(n.b))>=t}function Kat(e,t){this.g=e,this.d=he(le(wg,1),m2,10,0,[t])}function Wat(e){this.c=e,this.b=new Kp(l(Xr(new tl),50))}function Yat(e){this.c=e,this.b=new Kp(l(Xr(new l5),50))}function Xat(e){this.b=e,this.a=new Kp(l(Xr(new Bi),50))}function Qat(){this.b=new Ks,this.d=new os,this.e=new Fwe}function R5e(){this.c=new qa,this.d=new qa,this.e=new qa}function Tw(){this.a=new bl,this.b=(Mh(3,Yy),new Bu(3))}function Jp(e,t){this.e=e,this.a=wa,this.b=Qbt(t),this.c=t}function MH(e){this.c=e.c,this.d=e.d,this.b=e.b,this.a=e.a}function Jat(e,t,n,r,a,o){this.a=e,Joe.call(this,t,n,r,a,o)}function Zat(e,t,n,r,a,o){this.a=e,Joe.call(this,t,n,r,a,o)}function db(e,t,n,r,a,o,f){return new Eoe(e.e,t,n,r,a,o,f)}function Ppn(e,t,n){return n>=0&&vn(e.substr(n,t.length),t)}function eot(e,t){return De(t,149)&&vn(e.b,l(t,149).Pg())}function Bpn(e,t){return e.a?t.Gh().Kc():l(t.Gh(),71).Ii()}function tot(e,t){var n;return n=e.b.Qc(t),Yct(n,e.b.gc()),n}function UO(e,t){if(e==null)throw ue(new D8(t));return e}function dc(e){return e.u||(Yl(e),e.u=new Nrt(e,e)),e.u}function ooe(e){this.a=(Cn(),De(e,59)?new ese(e):new jq(e))}function sl(e){var t;return t=l(Kn(e,16),29),t||e.ii()}function DH(e,t){var n;return n=_m(e.Rm),t==null?n:n+": "+t}function tf(e,t,n){return Ga(t,n,e.length),e.substr(t,n-t)}function not(e,t){Vq.call(this),Y6e(this),this.a=e,this.c=t}function Fpn(e){e&&DH(e,e.ie())}function Rpn(e){Hz(),b.setTimeout(function(){throw e},0)}function jpn(){return ZV(),he(le(k_e,1),it,436,0,[j0e,x_e])}function $pn(){return aV(),he(le(T_e,1),it,435,0,[E_e,$0e])}function zpn(){return oV(),he(le(J_e,1),it,432,0,[Q0e,yK])}function qpn(){return dE(),he(le($8t,1),it,517,0,[dB,h1e])}function Hpn(){return zH(),he(le(PLe,1),it,429,0,[z1e,NLe])}function Vpn(){return pN(),he(le(wLe,1),it,428,0,[XK,vLe])}function Upn(){return JH(),he(le(hLe,1),it,431,0,[lLe,S1e])}function Gpn(){return dN(),he(le(_De,1),it,430,0,[kde,Ede])}function Kpn(){return oA(),he(le(DEt,1),it,531,0,[uM,cM])}function Wpn(){return kV(),he(le(EIe,1),it,501,0,[$W,X6])}function Ypn(){return xd(),he(le(REt,1),it,523,0,[w3,T2])}function Xpn(){return D1(),he(le($Et,1),it,522,0,[wv,Y1])}function Qpn(){return J0(),he(le(tTt,1),it,528,0,[E4,qb])}function Jpn(){return cN(),he(le(kLe,1),it,488,0,[xLe,JK])}function Zpn(){return GH(),he(le(fOe,1),it,491,0,[dge,hOe])}function e2n(){return fce(),he(le(vOe,1),it,492,0,[bOe,mOe])}function t2n(){return RH(),he(le(kIe,1),it,433,0,[Ude,xIe])}function n2n(){return eV(),he(le(CIe,1),it,434,0,[TIe,Qde])}function r2n(){return Sw(),he(le(cTt,1),it,465,0,[Hb,K6])}function i2n(){return rN(),he(le(yOe,1),it,438,0,[vge,QW])}function s2n(){return CN(),he(le(qOe,1),it,437,0,[ZW,zOe])}function a2n(){return mae(),he(le(gY,1),it,347,0,[rPe,iPe])}function IH(e,t,n,r){return n>=0?e.Uh(t,n,r):e.Ch(null,n,r)}function GO(e){return e.b.b==0?e.a.sf():kae(e.b)}function o2n(e){if(e.p!=5)throw ue(new pl);return Yr(e.f)}function c2n(e){if(e.p!=5)throw ue(new pl);return Yr(e.k)}function j5e(e){return qe(e.a)===qe((lce(),npe))&&aMn(e),e.a}function u2n(e,t){e.b=t,e.c>0&&e.b>0&&(e.g=aH(e.c,e.b,e.a))}function l2n(e,t){e.c=t,e.c>0&&e.b>0&&(e.g=aH(e.c,e.b,e.a))}function rot(e,t){ce(this,new lt(e.a,e.b)),ve(this,PO(t))}function Cw(){Qcn.call(this,new N8(Ay(12))),Tye(!0),this.a=2}function coe(e,t,n){Di(),Xv.call(this,e),this.b=t,this.a=n}function $5e(e,t,n){Jh(),Nz.call(this,t),this.a=e,this.b=n}function iot(e){var t;t=e.c.d.b,e.b=t,e.a=e.c.d,t.a=e.c.d.b=e}function h2n(e){return e.b==0?null:(mr(e.b!=0),af(e,e.a.a))}function xu(e,t){return t==null?hc(zo(e.f,null)):y_(e.i,t)}function sot(e,t,n,r,a){return new Bue(e,(rE(),P0e),t,n,r,a)}function OH(e,t){return Gct(t),Pwn(e,We(Vr,di,28,t,15,1),t)}function NH(e,t){return _H(e,"set1"),_H(t,"set2"),new GZe(e,t)}function f2n(e,t){var n=C0e[e.charCodeAt(0)];return n??e}function aot(e,t){var n,r;return n=t,r=new xt,Ovt(e,n,r),r.d}function uoe(e,t,n,r){var a;a=new Frt,t.a[n.g]=a,Q8(e.b,r,a)}function d2n(e,t){var n;return n=Iwn(e.f,t),Oi(Hq(n),e.f.d)}function KO(e){var t;Hwn(e.a),dnt(e.a),t=new e_(e.a),S8e(t)}function g2n(e,t){zbt(e,!0),Vu(e.e.Rf(),new v4e(e,!0,t))}function p2n(e,t){return tx(),e==ds(cg(t))||e==ds(Eb(t))}function b2n(e,t){return tp(),l(Q(t,(Hc(),$d)),17).a==e}function ua(e){return Math.max(Math.min(e,Ii),-2147483648)|0}function oot(e){this.a=l(Xr(e),277),this.b=(Cn(),new Dye(e))}function cot(e,t,n){this.i=new bt,this.b=e,this.g=t,this.a=n}function z5e(e,t,n){this.a=new bt,this.e=e,this.f=t,this.c=n}function PH(e,t,n){this.c=new bt,this.e=e,this.f=t,this.b=n}function uot(e){Vq.call(this),Y6e(this),this.a=e,this.c=!0}function m2n(e){function t(){}return t.prototype=e||{},new t}function v2n(e){if(e.Ae())return null;var t=e.n;return sK[t]}function WO(e){return e.Db>>16!=3?null:l(e.Cb,27)}function M1(e){return e.Db>>16!=9?null:l(e.Cb,27)}function lot(e){return e.Db>>16!=6?null:l(e.Cb,74)}function Sw(){Sw=U,Hb=new H3e(Mx,0),K6=new H3e(Dx,1)}function xd(){xd=U,w3=new $3e(Dx,0),T2=new $3e(Mx,1)}function D1(){D1=U,wv=new z3e(whe,0),Y1=new z3e("UP",1)}function hot(){hot=U,o6t=Kr(($z(),he(le(a6t,1),it,549,0,[E0e])))}function fot(e){var t;return t=new Kz(Ay(e.length)),j7e(t,e),t}function dot(e,t){return e.b+=t.b,e.c+=t.c,e.d+=t.d,e.a+=t.a,e}function w2n(e,t){return Zft(e,t)?(Yht(e),!0):!1}function Wg(e,t){if(t==null)throw ue(new S8);return j5n(e,t)}function YO(e,t){var n;n=e.q.getHours(),e.q.setDate(t),XA(e,n)}function q5e(e,t,n){var r;r=e.Ih(t),r>=0?e.bi(r,n):$9e(e,t,n)}function got(e,t){var n;return n=e.Ih(t),n>=0?e.Wh(n):que(e,t)}function pot(e,t){var n;for(Xr(t),n=e.a;n;n=n.c)t.Yd(n.g,n.i)}function loe(e,t,n){var r;r=w0t(e,t,n),e.b=new TV(r.c.length)}function U5(e,t,n){BH(),e&&ki(Zge,e,t),e&&ki(lF,e,n)}function y2n(e,t){return Yq(),Hn(),l(t.a,17).a0}function H5e(e){var t;return t=e.d,t=e.bj(e.f),qr(e,t),t.Ob()}function bot(e,t){var n;return n=new K4e(t),zgt(n,e),new Ol(n)}function E2n(e){if(e.p!=0)throw ue(new pl);return I_(e.f,0)}function T2n(e){if(e.p!=0)throw ue(new pl);return I_(e.k,0)}function mot(e){return e.Db>>16!=7?null:l(e.Cb,241)}function Qk(e){return e.Db>>16!=6?null:l(e.Cb,241)}function vot(e){return e.Db>>16!=7?null:l(e.Cb,167)}function ds(e){return e.Db>>16!=11?null:l(e.Cb,27)}function ky(e){return e.Db>>16!=17?null:l(e.Cb,29)}function wot(e){return e.Db>>16!=3?null:l(e.Cb,155)}function V5e(e){var t;return xb(e),t=new Ks,Fi(e,new k5(t))}function yot(e,t){var n=e.a=e.a||[];return n[t]||(n[t]=e.ve(t))}function C2n(e,t){var n;n=e.q.getHours(),e.q.setMonth(t),XA(e,n)}function xot(e,t){Fq(this),this.f=t,this.g=e,SH(this),this.je()}function kot(e,t){this.a=e,this.c=Ja(this.a),this.b=new MH(t)}function Eot(e,t,n){this.a=t,this.c=e,this.b=(Xr(n),new Ol(n))}function Tot(e,t,n){this.a=t,this.c=e,this.b=(Xr(n),new Ol(n))}function Cot(e){this.a=e,this.b=We(AEt,dt,2043,e.e.length,0,2)}function Sot(){this.a=new bd,this.e=new Ks,this.g=0,this.i=0}function BH(){BH=U,Zge=new Pr,lF=new Pr,wln(C6t,new LS)}function _ot(){_ot=U,fEt=yl(new Xs,(uo(),mc),(vo(),gB))}function U5e(){U5e=U,dEt=yl(new Xs,(uo(),mc),(vo(),gB))}function Aot(){Aot=U,pEt=yl(new Xs,(uo(),mc),(vo(),gB))}function Lot(){Lot=U,OEt=fi(new Xs,(uo(),mc),(vo(),zL))}function Sh(){Sh=U,BEt=fi(new Xs,(uo(),mc),(vo(),zL))}function Mot(){Mot=U,FEt=fi(new Xs,(uo(),mc),(vo(),zL))}function foe(){foe=U,qEt=fi(new Xs,(uo(),mc),(vo(),zL))}function rA(e,t,n,r,a,o){return new Zg(e.e,t,e.Lj(),n,r,a,o)}function rc(e,t,n){return t==null?ju(e.f,null,n):Bw(e.i,t,n)}function po(e,t){e.c&&al(e.c.g,e),e.c=t,e.c&&vt(e.c.g,e)}function Va(e,t){e.c&&al(e.c.a,e),e.c=t,e.c&&vt(e.c.a,e)}function Mc(e,t){e.i&&al(e.i.j,e),e.i=t,e.i&&vt(e.i.j,e)}function Fa(e,t){e.d&&al(e.d.e,e),e.d=t,e.d&&vt(e.d.e,e)}function doe(e,t){e.a&&al(e.a.k,e),e.a=t,e.a&&vt(e.a.k,e)}function goe(e,t){e.b&&al(e.b.f,e),e.b=t,e.b&&vt(e.b.f,e)}function Dot(e,t){Fgn(e,e.b,e.c),l(e.b.b,68),t&&l(t.b,68).b}function S2n(e,t){return Yi(l(e.c,65).c.e.b,l(t.c,65).c.e.b)}function _2n(e,t){return Yi(l(e.c,65).c.e.a,l(t.c,65).c.e.a)}function A2n(e){return Mce(),Hn(),l(e.a,86).d.e!=0}function FH(e,t){De(e.Cb,184)&&(l(e.Cb,184).tb=null),Fu(e,t)}function poe(e,t){De(e.Cb,90)&&zy(Yl(l(e.Cb,90)),4),Fu(e,t)}function L2n(e,t){m8e(e,t),De(e.Cb,90)&&zy(Yl(l(e.Cb,90)),2)}function M2n(e,t){var n,r;n=t.c,r=n!=null,r&&J8(e,new yy(t.c))}function Iot(e){var t,n;return n=(Sk(),t=new Qv,t),sE(n,e),n}function Oot(e){var t,n;return n=(Sk(),t=new Qv,t),sE(n,e),n}function Not(e){for(var t;;)if(t=e.Pb(),!e.Ob())return t}function D2n(e,t,n){return vt(e.a,(kH(),fue(t,n),new iw(t,n))),e}function ku(e,t){return Fo(),Voe(t)?new nH(t,e):new yO(t,e)}function XO(e){return Cd(),iu(e,0)>=0?kb(e):J_(kb(r2(e)))}function I2n(e){var t;return t=l(eH(e.b),9),new Zh(e.a,t,e.c)}function Pot(e,t){var n;return n=l(Oy(ex(e.a),t),16),n?n.gc():0}function Bot(e,t,n){var r;o1t(t,n,e.c.length),r=n-t,d3e(e.c,t,r)}function Zp(e,t,n){o1t(t,n,e.gc()),this.c=e,this.a=t,this.b=n-t}function nx(e){this.c=new os,this.b=e.b,this.d=e.c,this.a=e.a}function boe(e){this.a=b.Math.cos(e),this.b=b.Math.sin(e)}function Pm(e,t,n,r){this.c=e,this.d=r,doe(this,t),goe(this,n)}function G5e(e,t){Ycn.call(this,new N8(Ay(e))),Mh(t,Dwt),this.a=t}function Fot(e,t,n){return new Bue(e,(rE(),N0e),null,!1,t,n)}function Rot(e,t,n){return new Bue(e,(rE(),B0e),t,n,null,!1)}function O2n(){return Fl(),he(le(oc,1),it,108,0,[y_e,Ec,i4])}function N2n(){return ol(),he(le(X6t,1),it,472,0,[a1,Fb,w0])}function P2n(){return Bl(),he(le(W6t,1),it,471,0,[Fd,Bb,v0])}function B2n(){return t1(),he(le(s4,1),it,237,0,[Gc,$u,Kc])}function F2n(){return lA(),he(le(dAe,1),it,391,0,[t1e,e1e,n1e])}function R2n(){return Ow(),he(le(m1e,1),it,372,0,[o3,Rb,a3])}function j2n(){return dA(),he(le(dLe,1),it,322,0,[HL,mB,fLe])}function $2n(){return pV(),he(le(pLe,1),it,351,0,[gLe,YK,_1e])}function z2n(){return Vm(),he(le(mxt,1),it,460,0,[M1e,FT,P6])}function q2n(){return vE(),he(le($1e,1),it,299,0,[R1e,j1e,vB])}function H2n(){return ep(),he(le(Cxt,1),it,311,0,[wB,F6,Ux])}function V2n(){return EA(),he(le(mDe,1),it,390,0,[pde,bDe,SW])}function U2n(){return qo(),he(le(sEt,1),it,463,0,[sM,$l,zu])}function G2n(){return LV(),he(le(MDe,1),it,387,0,[ADe,Tde,LDe])}function K2n(){return yA(),he(le(DDe,1),it,349,0,[Sde,Cde,MB])}function W2n(){return SE(),he(le(ODe,1),it,350,0,[_de,IDe,aM])}function Y2n(){return gV(),he(le(BDe,1),it,352,0,[PDe,Ade,NDe])}function X2n(){return OV(),he(le(FDe,1),it,388,0,[Lde,XT,k4])}function Q2n(){return Iw(),he(le(SEt,1),it,464,0,[DB,oM,MW])}function I1(e){return Ic(he(le(Ea,1),dt,8,0,[e.i.n,e.n,e.a]))}function J2n(){return xA(),he(le(eIe,1),it,392,0,[ZDe,Ide,OB])}function jot(){jot=U,FTt=yl(new Xs,(wx(),hM),(WA(),VDe))}function RH(){RH=U,Ude=new V3e("DFS",0),xIe=new V3e("BFS",1)}function $ot(e,t,n){var r;r=new hte,r.b=t,r.a=n,++t.b,vt(e.d,r)}function Z2n(e,t,n){var r;r=new Eo(n.d),Oi(r,e),b8e(t,r.a,r.b)}function ebn(e,t){Ont(e,Yr(va(bw(t,24),ZU)),Yr(va(t,ZU)))}function Ey(e,t){if(e<0||e>t)throw ue(new tc(dEe+e+gEe+t))}function Sn(e,t){if(e<0||e>=t)throw ue(new tc(dEe+e+gEe+t))}function Xn(e,t){if(e<0||e>=t)throw ue(new e3e(dEe+e+gEe+t))}function kn(e,t){this.b=(nr(e),e),this.a=t&Xy?t:t|64|_d}function K5e(e){var t;return xb(e),t=(Ew(),Ew(),D0e),lV(e,t)}function tbn(e,t,n){var r;return r=ZA(e,t,!1),r.b<=t&&r.a<=n}function nbn(){return tV(),he(le(pOe,1),it,439,0,[gge,gOe,dOe])}function rbn(){return qV(),he(le(XIe,1),it,394,0,[YIe,uge,WIe])}function ibn(){return WV(),he(le(KIe,1),it,445,0,[RB,VW,rge])}function sbn(){return sU(),he(le(gCt,1),it,456,0,[ige,age,sge])}function abn(){return LN(),he(le(AIe,1),it,393,0,[zW,SIe,_Ie])}function obn(){return AV(),he(le(GIe,1),it,300,0,[nge,UIe,VIe])}function cbn(){return rp(),he(le(YNe,1),it,346,0,[oY,A2,DM])}function ubn(){return PN(),he(le(pge,1),it,444,0,[WW,YW,XW])}function lbn(){return F1(),he(le(FNe,1),it,278,0,[nC,_4,rC])}function hbn(){return dx(),he(le(nPe,1),it,280,0,[tPe,L4,dY])}function _w(e){return Xr(e),De(e,16)?new Ol(l(e,16)):$k(e.Kc())}function W5e(e,t){return e&&e.equals?e.equals(t):qe(e)===qe(t)}function va(e,t){return mb(rgn(wc(e)?Mf(e):e,wc(t)?Mf(t):t))}function Q0(e,t){return mb(ign(wc(e)?Mf(e):e,wc(t)?Mf(t):t))}function moe(e,t){return mb(sgn(wc(e)?Mf(e):e,wc(t)?Mf(t):t))}function fbn(e,t){var n;return n=(nr(e),e).g,qye(!!n),nr(t),n(t)}function zot(e,t){var n,r;return r=Hk(e,t),n=e.a.fd(r),new VZe(e,n)}function dbn(e){return e.Db>>16!=6?null:l(Uue(e),241)}function gbn(e){if(e.p!=2)throw ue(new pl);return Yr(e.f)&Zs}function pbn(e){if(e.p!=2)throw ue(new pl);return Yr(e.k)&Zs}function re(e){return mr(e.ar?1:0}function Uot(e,t){var n,r;return n=$oe(t),r=n,l(cr(e.c,r),17).a}function voe(e,t,n){var r;r=e.d[t.p],e.d[t.p]=e.d[n.p],e.d[n.p]=r}function Sbn(e,t,n){var r;e.n&&t&&n&&(r=new Kne,vt(e.e,r))}function woe(e,t){if(na(e.a,t),t.d)throw ue(new Ac(e3t));t.d=e}function Q5e(e,t){this.a=new bt,this.d=new bt,this.f=e,this.c=t}function Got(){this.c=new Lnt,this.a=new Put,this.b=new UQe,uet()}function Kot(){hx(),this.b=new Pr,this.a=new Pr,this.c=new bt}function Wot(e,t,n){this.d=e,this.j=t,this.e=n,this.o=-1,this.p=3}function Yot(e,t,n){this.d=e,this.k=t,this.f=n,this.o=-1,this.p=5}function Xot(e,t,n,r,a,o){Q6e.call(this,e,t,n,r,a),o&&(this.o=-2)}function Qot(e,t,n,r,a,o){J6e.call(this,e,t,n,r,a),o&&(this.o=-2)}function Jot(e,t,n,r,a,o){p6e.call(this,e,t,n,r,a),o&&(this.o=-2)}function Zot(e,t,n,r,a,o){t7e.call(this,e,t,n,r,a),o&&(this.o=-2)}function ect(e,t,n,r,a,o){b6e.call(this,e,t,n,r,a),o&&(this.o=-2)}function tct(e,t,n,r,a,o){Z6e.call(this,e,t,n,r,a),o&&(this.o=-2)}function nct(e,t,n,r,a,o){e7e.call(this,e,t,n,r,a),o&&(this.o=-2)}function rct(e,t,n,r,a,o){m6e.call(this,e,t,n,r,a),o&&(this.o=-2)}function ict(e,t,n,r){Nz.call(this,n),this.b=e,this.c=t,this.d=r}function sct(e,t){this.f=e,this.a=(eE(),SY),this.c=SY,this.b=t}function act(e,t){this.g=e,this.d=(eE(),_Y),this.a=_Y,this.b=t}function J5e(e,t){!e.c&&(e.c=new Ls(e,0)),HU(e.c,(Gi(),HM),t)}function _bn(e,t){return uTn(e,t,De(t,102)&&(l(t,19).Bb&Io)!=0)}function Abn(e,t){return $st(Zc(e.q.getTime()),Zc(t.q.getTime()))}function oct(e){return Cae(e.e.Rd().gc()*e.c.Rd().gc(),16,new pie(e))}function Lbn(e){return!!e.u&&du(e.u.a).i!=0&&!(e.n&&cue(e.n))}function Mbn(e){return!!e.a&&Xl(e.a.a).i!=0&&!(e.b&&uue(e.b))}function Z5e(e,t){return t==0?!!e.o&&e.o.f!=0:nue(e,t)}function Dbn(e,t,n){var r;return r=l(e.Zb().xc(t),16),!!r&&r.Hc(n)}function cct(e,t,n){var r;return r=l(e.Zb().xc(t),16),!!r&&r.Mc(n)}function uct(e,t){var n;return n=1-t,e.a[n]=EV(e.a[n],n),EV(e,t)}function lct(e,t){var n,r;return r=va(e,Vo),n=l0(t,32),Q0(n,r)}function hct(e,t,n){var r;r=(Xr(e),new Ol(e)),O7n(new Eot(r,t,n))}function QO(e,t,n){var r;r=(Xr(e),new Ol(e)),N7n(new Tot(r,t,n))}function zc(e,t,n,r,a,o){return qft(e,t,n,o),c8e(e,r),u8e(e,a),e}function fct(e,t,n,r){return e.a+=""+tf(t==null?ul:xc(t),n,r),e}function Ua(e,t){this.a=e,kr.call(this,e),Ey(t,e.gc()),this.b=t}function dct(e){this.a=We(wa,Rn,1,P7e(b.Math.max(8,e))<<1,5,1)}function JO(e){return l(j1(e,We(wg,m2,10,e.c.length,0,1)),199)}function kd(e){return l(j1(e,We(u1e,Bhe,18,e.c.length,0,1)),483)}function gct(e){return e.a?e.e.length==0?e.a.a:e.a.a+(""+e.e):e.c}function iA(e){for(;e.d>0&&e.a[--e.d]==0;);e.a[e.d++]==0&&(e.e=0)}function pct(e){return mr(e.b.b!=e.d.a),e.c=e.b=e.b.b,--e.a,e.c.c}function Ibn(e,t,n){e.a=t,e.c=n,e.b.a.$b(),Ch(e.d),ay(e.e.a.c,0)}function bct(e,t){var n;e.e=new Vwe,n=Hy(t),Vs(n,e.c),Mbt(e,n,0)}function Qs(e,t,n,r){var a;a=new J9,a.a=t,a.b=n,a.c=r,ui(e.a,a)}function gt(e,t,n,r){var a;a=new J9,a.a=t,a.b=n,a.c=r,ui(e.b,a)}function mct(e,t,n){if(e<0||tn)throw ue(new tc(U9n(e,t,n)))}function ZO(e,t){if(e<0||e>=t)throw ue(new tc(kkn(e,t)));return e}function Obn(e){if(!("stack"in e))try{throw e}catch{}return e}function G5(e){return p_(),De(e.g,10)?l(e.g,10):null}function Nbn(e){return V5(e).dc()?!1:(rhn(e,new oe),!0)}function Fm(e){var t;return wc(e)?(t=e,t==-0?0:t):Yvn(e)}function vct(e,t){return De(t,44)?gue(e.a,l(t,44)):!1}function wct(e,t){return De(t,44)?gue(e.a,l(t,44)):!1}function yct(e,t){return De(t,44)?gue(e.a,l(t,44)):!1}function e6e(e){var t;return fb(e),t=new Ne,A5(e.a,new x5(t)),t}function t6e(){var e,t,n;return t=(n=(e=new Qv,e),n),vt(RPe,t),t}function jH(e){var t;return fb(e),t=new gn,A5(e.a,new T8(t)),t}function Pbn(e,t){return e.a<=e.b?(t.Dd(e.a++),!0):!1}function xct(e){oce.call(this,e,(rE(),O0e),null,!1,null,!1)}function kct(){kct=U,A7t=Kr((Zz(),he(le(U_e,1),it,489,0,[G0e])))}function Ect(){Ect=U,jDe=pat(pt(1),pt(4)),RDe=pat(pt(1),pt(2))}function Bbn(e,t){return new wae(t,z_(Ja(t.e),e,e),(Hn(),!0))}function $H(e){return new Bu((Mh(e,Fle),cV(bo(bo(5,e),e/10|0))))}function Fbn(e){return Cae(e.e.Rd().gc()*e.c.Rd().gc(),273,new gie(e))}function Tct(e){return l(j1(e,We(F8t,I3t,12,e.c.length,0,1)),2042)}function Rbn(e){return Sh(),!Do(e)&&!(!Do(e)&&e.c.i.c==e.d.i.c)}function jbn(e,t){return ux(),l(Q(t,(Hc(),W6)),17).a>=e.gc()}function sA(e,t){xIn(t,e),N4e(e.d),N4e(l(Q(e,(Nt(),wW)),214))}function yoe(e,t){kIn(t,e),P4e(e.d),P4e(l(Q(e,(Nt(),wW)),214))}function $bn(e,t,n){e.d&&al(e.d.e,e),e.d=t,e.d&&pw(e.d.e,n,e)}function zbn(e,t,n){return n.f.c.length>0?u5e(e.a,t,n):u5e(e.b,t,n)}function qbn(e,t,n){var r;r=s6n();try{return Lfn(e,t,n)}finally{Nmn(r)}}function Aw(e,t){var n,r;return n=Wg(e,t),r=null,n&&(r=n.pe()),r}function aA(e,t){var n,r;return n=Wg(e,t),r=null,n&&(r=n.se()),r}function Jk(e,t){var n,r;return n=_y(e,t),r=null,n&&(r=n.se()),r}function Yg(e,t){var n,r;return n=Wg(e,t),r=null,n&&(r=e9e(n)),r}function Hbn(e,t,n){var r;return r=NE(n),RU(e.g,r,t),RU(e.i,t,n),t}function n6e(e,t,n){this.d=new OYe(this),this.e=e,this.i=t,this.f=n}function Cct(e,t,n,r){this.e=null,this.c=e,this.d=t,this.a=n,this.b=r}function Sct(e,t,n,r){Ent(this),this.c=e,this.e=t,this.f=n,this.b=r}function r6e(e,t,n,r){this.d=e,this.n=t,this.g=n,this.o=r,this.p=-1}function _ct(e,t,n,r){return De(n,59)?new rrt(e,t,n,r):new r5e(e,t,n,r)}function Zk(e){return De(e,16)?l(e,16).dc():!e.Kc().Ob()}function Act(e){if(e.e.g!=e.b)throw ue(new Xh);return!!e.c&&e.d>0}function Br(e){return mr(e.b!=e.d.c),e.c=e.b,e.b=e.b.a,++e.a,e.c.c}function i6e(e,t){nr(t),Ts(e.a,e.c,t),e.c=e.c+1&e.a.length-1,Xdt(e)}function gb(e,t){nr(t),e.b=e.b-1&e.a.length-1,Ts(e.a,e.b,t),Xdt(e)}function Lct(e){var t;t=e.Gh(),this.a=De(t,71)?l(t,71).Ii():t.Kc()}function Vbn(e){return new kn(Lwn(l(e.a.md(),16).gc(),e.a.ld()),16)}function Mct(){Mct=U,UCt=Kr((nq(),he(le(wOe,1),it,490,0,[bge])))}function Dct(){Dct=U,KCt=Kr((rq(),he(le(GCt,1),it,558,0,[mge])))}function Ict(){Ict=U,hSt=Kr((b_(),he(le($Oe,1),it,539,0,[qB])))}function Ubn(){return Km(),he(le(mAe,1),it,389,0,[c4,bAe,o1e,c1e])}function Gbn(){return rE(),he(le(fK,1),it,304,0,[O0e,N0e,P0e,B0e])}function Kbn(){return bx(),he(le(E7t,1),it,332,0,[aB,sB,oB,cB])}function Wbn(){return NA(),he(le(S7t,1),it,406,0,[uB,bK,mK,lB])}function Ybn(){return Pw(),he(le(x7t,1),it,417,0,[iB,rB,V0e,U0e])}function Xbn(){return wE(),he(le(C8t,1),it,416,0,[s3,o4,a4,M6])}function Qbn(){return R1(),he(le(txt,1),it,421,0,[Vx,MT,DT,b1e])}function Jbn(){return IV(),he(le(V8t,1),it,371,0,[p1e,HK,VK,pB])}function Zbn(){return By(),he(le(mde,1),it,203,0,[_W,bde,G6,U6])}function emn(){return Ed(),he(le(SDe,1),it,284,0,[E2,CDe,yde,xde])}function tmn(e){var t;return e.j==(Ct(),Dr)&&(t=v2t(e),vl(t,ar))}function nmn(e,t){var n;n=t.a,po(n,t.c.d),Fa(n,t.d.d),Dy(n.a,e.n)}function s6e(e,t){var n;return n=l(B1(e.b,t),67),!n&&(n=new os),n}function ix(e){return p_(),De(e.g,154)?l(e.g,154):null}function rmn(e){e.a=null,e.e=null,ay(e.b.c,0),ay(e.f.c,0),e.c=null}function zH(){zH=U,z1e=new F3e(cT,0),NLe=new F3e("TOP_LEFT",1)}function oA(){oA=U,uM=new j3e("UPPER",0),cM=new j3e("LOWER",1)}function imn(e,t){return z8(new lt(t.e.a+t.f.a/2,t.e.b+t.f.b/2),e)}function Oct(e,t){return l(fh(vy(l($i(e.k,t),15).Oc(),I6)),113)}function Nct(e,t){return l(fh(Y8(l($i(e.k,t),15).Oc(),I6)),113)}function smn(){return wx(),he(le(qDe,1),it,405,0,[NW,lM,hM,fM])}function amn(){return kA(),he(le(yIe,1),it,353,0,[Vde,jW,Hde,qde])}function omn(){return uU(),he(le(HIe,1),it,354,0,[tge,zIe,qIe,$Ie])}function cmn(){return mh(),he(le(BM,1),it,386,0,[iF,Cv,rF,A4])}function umn(){return Ih(),he(le(JSt,1),it,291,0,[eF,kg,Gb,ZB])}function lmn(){return ip(),he(le(Vge,1),it,223,0,[Hge,JB,iC,s9])}function hmn(){return VV(),he(le(cPe,1),it,320,0,[Kge,sPe,oPe,aPe])}function fmn(){return NV(),he(le(p_t,1),it,415,0,[Wge,lPe,uPe,hPe])}function dmn(e){return BH(),Hu(Zge,e)?l(cr(Zge,e),341).Qg():null}function nf(e,t,n){return t<0?que(e,n):l(n,69).wk().Bk(e,e.hi(),t)}function gmn(e,t,n){var r;return r=NE(n),RU(e.j,r,t),ki(e.k,t,n),t}function pmn(e,t,n){var r;return r=NE(n),RU(e.d,r,t),ki(e.e,t,n),t}function Pct(e){var t,n;return t=(rb(),n=new TI,n),e&&AU(t,e),t}function a6e(e){var t;return t=e.aj(e.i),e.i>0&&pu(e.g,0,t,0,e.i),t}function Bct(e,t){var n;for(n=e.j.c.length;n>24}function mmn(e){if(e.p!=1)throw ue(new pl);return Yr(e.k)<<24>>24}function vmn(e){if(e.p!=7)throw ue(new pl);return Yr(e.k)<<16>>16}function wmn(e){if(e.p!=7)throw ue(new pl);return Yr(e.f)<<16>>16}function K5(e,t){return t.e==0||e.e==0?BL:(GE(),Que(e,t))}function jct(e,t){return qe(t)===qe(e)?"(this Map)":t==null?ul:xc(t)}function ymn(e,t,n){return Nae(Ge(hc(zo(e.f,t))),Ge(hc(zo(e.f,n))))}function xmn(e,t,n){var r;r=l(cr(e.g,n),60),vt(e.a.c,new ca(t,r))}function $ct(e,t,n){e.i=0,e.e=0,t!=n&&(k0t(e,t,n),x0t(e,t,n))}function kmn(e,t,n,r,a){var o;o=ETn(a,n,r),vt(t,pkn(a,o)),a9n(e,a,t)}function o6e(e,t,n,r,a){this.i=e,this.a=t,this.e=n,this.j=r,this.f=a}function zct(e,t){R5e.call(this),this.a=e,this.b=t,vt(this.a.b,this)}function qct(e){this.b=new Pr,this.c=new Pr,this.d=new Pr,this.a=e}function Hct(e,t){var n;return n=new S5,e.Gd(n),n.a+="..",t.Hd(n),n.a}function Vct(e,t){var n;for(n=t;n;)dw(e,n.i,n.j),n=ds(n);return e}function Uct(e,t,n){var r;return r=NE(n),ki(e.b,r,t),ki(e.c,t,n),t}function Xg(e){var t;for(t=0;e.Ob();)e.Pb(),t=bo(t,1);return cV(t)}function sg(e,t){Fo();var n;return n=l(e,69).vk(),k9n(n,t),n.xl(t)}function Emn(e,t,n){if(n){var r=n.oe();e.a[t]=r(n)}else delete e.a[t]}function c6e(e,t){var n;n=e.q.getHours(),e.q.setFullYear(t+Lb),XA(e,n)}function Tmn(e,t){return l(t==null?hc(zo(e.f,null)):y_(e.i,t),288)}function u6e(e,t){return e==(Zn(),Ps)&&t==Ps?4:e==Ps||t==Ps?8:32}function qH(e,t,n){return $U(e,t,n,De(t,102)&&(l(t,19).Bb&Io)!=0)}function Cmn(e,t,n){return XE(e,t,n,De(t,102)&&(l(t,19).Bb&Io)!=0)}function Smn(e,t,n){return bTn(e,t,n,De(t,102)&&(l(t,19).Bb&Io)!=0)}function l6e(e){e.b!=e.c&&(e.a=We(wa,Rn,1,8,5,1),e.b=0,e.c=0)}function cA(e){return mr(e.a=0&&e.a[n]===t[n];n--);return n<0}function HH(e){var t;return e?new K4e(e):(t=new bd,sce(t,e),t)}function Omn(e,t){var n,r;r=!1;do n=h0t(e,t),r=r|n;while(n);return r}function Nmn(e){e&&awn((Xwe(),GSe)),--aK,e&&oK!=-1&&(Cln(oK),oK=-1)}function VH(e){Rxe(),Ont(this,Yr(va(bw(e,24),ZU)),Yr(va(e,ZU)))}function Xct(){Xct=U,q6t=Kr((ZV(),he(le(k_e,1),it,436,0,[j0e,x_e])))}function Qct(){Qct=U,H6t=Kr((aV(),he(le(T_e,1),it,435,0,[E_e,$0e])))}function Jct(){Jct=U,U7t=Kr((oV(),he(le(J_e,1),it,432,0,[Q0e,yK])))}function Zct(){Zct=U,z8t=Kr((dE(),he(le($8t,1),it,517,0,[dB,h1e])))}function eut(){eut=U,_xt=Kr((zH(),he(le(PLe,1),it,429,0,[z1e,NLe])))}function tut(){tut=U,bxt=Kr((pN(),he(le(wLe,1),it,428,0,[XK,vLe])))}function nut(){nut=U,yxt=Kr((cN(),he(le(kLe,1),it,488,0,[xLe,JK])))}function rut(){rut=U,iEt=Kr((dN(),he(le(_De,1),it,430,0,[kde,Ede])))}function iut(){iut=U,IEt=Kr((oA(),he(le(DEt,1),it,531,0,[uM,cM])))}function sut(){sut=U,fxt=Kr((JH(),he(le(hLe,1),it,431,0,[lLe,S1e])))}function aut(){aut=U,BTt=Kr((RH(),he(le(kIe,1),it,433,0,[Ude,xIe])))}function out(){out=U,zTt=Kr((kV(),he(le(EIe,1),it,501,0,[$W,X6])))}function cut(){cut=U,jEt=Kr((xd(),he(le(REt,1),it,523,0,[w3,T2])))}function uut(){uut=U,zEt=Kr((D1(),he(le($Et,1),it,522,0,[wv,Y1])))}function lut(){lut=U,nTt=Kr((J0(),he(le(tTt,1),it,528,0,[E4,qb])))}function hut(){hut=U,uTt=Kr((Sw(),he(le(cTt,1),it,465,0,[Hb,K6])))}function fut(){fut=U,VTt=Kr((eV(),he(le(CIe,1),it,434,0,[TIe,Qde])))}function dut(){dut=U,jCt=Kr((GH(),he(le(fOe,1),it,491,0,[dge,hOe])))}function gut(){gut=U,zCt=Kr((fce(),he(le(vOe,1),it,492,0,[bOe,mOe])))}function put(){put=U,WCt=Kr((rN(),he(le(yOe,1),it,438,0,[vge,QW])))}function but(){but=U,fSt=Kr((CN(),he(le(qOe,1),it,437,0,[ZW,zOe])))}function mut(){mut=U,f_t=Kr((mae(),he(le(gY,1),it,347,0,[rPe,iPe])))}function Pmn(){return Js(),he(le(LM,1),it,88,0,[J1,vc,uc,Q1,wf])}function Bmn(){return Ct(),he(le(Oo,1),au,64,0,[Pc,Qn,ar,Dr,er])}function Fmn(e,t,n){return l(t==null?ju(e.f,null,n):Bw(e.i,t,n),288)}function Rmn(e){return(e.k==(Zn(),Ps)||e.k==Us)&&ns(e,(ft(),KL))}function Coe(e){return e.c&&e.d?X5e(e.c)+"->"+X5e(e.d):"e_"+fw(e)}function to(e,t){var n,r;for(nr(t),r=e.Kc();r.Ob();)n=r.Pb(),t.Cd(n)}function jmn(e,t){var n;n=new M8,Nm(n,"x",t.a),Nm(n,"y",t.b),J8(e,n)}function $mn(e,t){var n;n=new M8,Nm(n,"x",t.a),Nm(n,"y",t.b),J8(e,n)}function vut(e,t){var n;for(n=t;n;)dw(e,-n.i,-n.j),n=ds(n);return e}function f6e(e,t){var n,r;for(n=t,r=0;n>0;)r+=e.a[n],n-=n&-n;return r}function rf(e,t,n){var r;return r=(Sn(t,e.c.length),e.c[t]),e.c[t]=n,r}function d6e(e,t,n){e.a.c.length=0,hMn(e,t,n),e.a.c.length==0||j_n(e,t)}function eN(e){e.i=0,aO(e.b,null),aO(e.c,null),e.a=null,e.e=null,++e.g}function UH(){UH=U,G1=!0,I6t=!1,O6t=!1,P6t=!1,N6t=!1}function Soe(e){UH(),!G1&&(this.c=e,this.e=!0,this.a=new bt)}function wut(e,t){this.c=0,this.b=t,qtt.call(this,e,17493),this.a=this.c}function yut(e){kwt(),SQe(this),this.a=new os,G7e(this,e),ui(this.a,e)}function xut(){Yse(this),this.b=new lt(gs,gs),this.a=new lt(ia,ia)}function GH(){GH=U,dge=new K3e(HEe,0),hOe=new K3e("TARGET_WIDTH",1)}function W5(e,t){return(xb(e),_k(new bn(e,new $6e(t,e.a)))).Bd(zx)}function zmn(){return uo(),he(le(gAe,1),it,367,0,[y0,vg,bu,_u,mc])}function qmn(){return Ry(),he(le(rxt,1),it,375,0,[bB,KK,WK,GK,UK])}function Hmn(){return l2(),he(le(mLe,1),it,348,0,[A1e,bLe,L1e,BT,PT])}function Vmn(){return OA(),he(le(wDe,1),it,323,0,[vDe,vde,wde,rM,iM])}function Umn(){return hf(),he(le(WLe,1),it,171,0,[EB,YL,$b,XL,d4])}function Gmn(){return bU(),he(le(qTt,1),it,368,0,[Yde,Gde,Xde,Kde,Wde])}function Kmn(){return VA(),he(le(qCt,1),it,373,0,[Q6,e9,xM,yM,zB])}function Wmn(){return XN(),he(le(TOe,1),it,324,0,[xOe,wge,EOe,yge,kOe])}function Ymn(){return r1(),he(le(xg,1),it,170,0,[Pn,ha,zd,yv,S2])}function Xmn(){return t6(),he(le(OM,1),it,256,0,[Kb,tF,XNe,IM,QNe])}function Qmn(e){return Hz(),function(){return qbn(e,this,arguments)}}function Do(e){return!e.c||!e.d?!1:!!e.c.i&&e.c.i==e.d.i}function g6e(e,t){return De(t,143)?vn(e.c,l(t,143).c):!1}function Yl(e){return e.t||(e.t=new bQe(e),_A(new IJe(e),0,e.t)),e.t}function kut(e){this.b=e,or.call(this,e),this.a=l(Kn(this.b.a,4),129)}function Eut(e){this.b=e,H8.call(this,e),this.a=l(Kn(this.b.a,4),129)}function h0(e,t,n,r,a){Out.call(this,t,r,a),this.c=e,this.b=n}function p6e(e,t,n,r,a){Wot.call(this,t,r,a),this.c=e,this.a=n}function b6e(e,t,n,r,a){Yot.call(this,t,r,a),this.c=e,this.a=n}function m6e(e,t,n,r,a){Out.call(this,t,r,a),this.c=e,this.a=n}function _oe(e,t){var n;return n=l(B1(e.d,t),23),n||l(B1(e.e,t),23)}function Tut(e,t){var n,r;return n=t.ld(),r=e.Fe(n),!!r&&Jc(r.e,t.md())}function Cut(e,t){var n;return n=t.ld(),new iw(n,e.e.pc(n,l(t.md(),16)))}function Jmn(e,t){var n;return n=e.a.get(t),n??We(wa,Rn,1,0,5,1)}function Sut(e){var t;return t=e.length,vn(sr.substr(sr.length-t,t),e)}function xr(e){if(jr(e))return e.c=e.a,e.a.Pb();throw ue(new _c)}function v6e(e,t){return t==0||e.e==0?e:t>0?pbt(e,t):j1t(e,-t)}function sx(e,t){return t==0||e.e==0?e:t>0?j1t(e,t):pbt(e,-t)}function w6e(e){uln.call(this,e==null?ul:xc(e),De(e,82)?l(e,82):null)}function _ut(e){var t;return e.c||(t=e.r,De(t,90)&&(e.c=l(t,29))),e.c}function Aoe(e){var t;return t=new Tw,pc(t,e),rt(t,(Nt(),cc),null),t}function Aut(e){var t,n;return t=e.c.i,n=e.d.i,t.k==(Zn(),Us)&&n.k==Us}function Loe(e){var t,n,r;return t=e&eh,n=e>>22&eh,r=e<0?hp:0,qu(t,n,r)}function Zmn(e){var t,n,r,a;for(n=e,r=0,a=n.length;r=0?e.Lh(r,n,!0):Hw(e,t,n)}function tvn(e,t,n){return Yi(z8(BE(e),Ja(t.b)),z8(BE(e),Ja(n.b)))}function nvn(e,t,n){return Yi(z8(BE(e),Ja(t.e)),z8(BE(e),Ja(n.e)))}function rvn(e,t){return b.Math.min(pb(t.a,e.d.d.c),pb(t.b,e.d.d.c))}function tN(e,t){e._i(e.i+1),R_(e,e.i,e.Zi(e.i,t)),e.Mi(e.i++,t),e.Ni()}function uA(e){var t,n;++e.j,t=e.g,n=e.i,e.g=null,e.i=0,e.Oi(n,t),e.Ni()}function Lut(e,t,n){var r;r=new vye(e.a),bA(r,e.a.a),ju(r.f,t,n),e.a.a=r}function y6e(e,t,n,r){var a;for(a=0;at)throw ue(new tc(u9e(e,t,"index")));return e}function t2(e,t){var n;return n=(Sn(t,e.c.length),e.c[t]),d3e(e.c,t,1),n}function E6e(e,t){var n,r;return n=(nr(e),e),r=(nr(t),t),n==r?0:nt.p?-1:0}function Fut(e){var t;return e.a||(t=e.r,De(t,156)&&(e.a=l(t,156))),e.a}function uvn(e,t,n){var r;return++e.e,--e.f,r=l(e.d[t].gd(n),136),r.md()}function lvn(e){var t,n;return t=e.ld(),n=l(e.md(),16),NO(n.Nc(),new bie(t))}function Rut(e,t){return Hu(e.a,t)?(ax(e.a,t),!0):!1}function ox(e,t,n){return ZO(t,e.e.Rd().gc()),ZO(n,e.c.Rd().gc()),e.a[t][n]}function WH(e,t,n){this.a=e,this.b=t,this.c=n,vt(e.t,this),vt(t.i,this)}function YH(e,t,n,r){this.f=e,this.e=t,this.d=n,this.b=r,this.c=r?r.d:null}function nN(){this.b=new os,this.a=new os,this.b=new os,this.a=new os}function eE(){eE=U;var e,t;SY=(Sk(),t=new Fz,t),_Y=(e=new zie,e)}function hvn(e){var t;return xb(e),t=new Mit(e,e.a.e,e.a.d|4),new Vye(e,t)}function jut(e){var t;for(fb(e),t=0;e.a.Bd(new An);)t=bo(t,1);return t}function XH(e,t){return nr(t),e.c=0,"Initial capacity must not be negative")}function QH(){QH=U,kM=new Ui("org.eclipse.elk.labels.labelManager")}function $ut(){$ut=U,sLe=new vs("separateLayerConnections",(IV(),p1e))}function J0(){J0=U,E4=new q3e("REGULAR",0),qb=new q3e("CRITICAL",1)}function rN(){rN=U,vge=new Y3e("FIXED",0),QW=new Y3e("CENTER_NODE",1)}function JH(){JH=U,lLe=new N3e("QUADRATIC",0),S1e=new N3e("SCANLINE",1)}function zut(){zut=U,dxt=Kr((dA(),he(le(dLe,1),it,322,0,[HL,mB,fLe])))}function qut(){qut=U,gxt=Kr((pV(),he(le(pLe,1),it,351,0,[gLe,YK,_1e])))}function Hut(){Hut=U,uxt=Kr((Ow(),he(le(m1e,1),it,372,0,[o3,Rb,a3])))}function Vut(){Vut=U,vxt=Kr((Vm(),he(le(mxt,1),it,460,0,[M1e,FT,P6])))}function Uut(){Uut=U,Txt=Kr((vE(),he(le($1e,1),it,299,0,[R1e,j1e,vB])))}function Gut(){Gut=U,Sxt=Kr((ep(),he(le(Cxt,1),it,311,0,[wB,F6,Ux])))}function Kut(){Kut=U,Zkt=Kr((EA(),he(le(mDe,1),it,390,0,[pde,bDe,SW])))}function Wut(){Wut=U,oEt=Kr((LV(),he(le(MDe,1),it,387,0,[ADe,Tde,LDe])))}function Yut(){Yut=U,cEt=Kr((yA(),he(le(DDe,1),it,349,0,[Sde,Cde,MB])))}function Xut(){Xut=U,aEt=Kr((qo(),he(le(sEt,1),it,463,0,[sM,$l,zu])))}function Qut(){Qut=U,uEt=Kr((SE(),he(le(ODe,1),it,350,0,[_de,IDe,aM])))}function Jut(){Jut=U,lEt=Kr((gV(),he(le(BDe,1),it,352,0,[PDe,Ade,NDe])))}function Zut(){Zut=U,hEt=Kr((OV(),he(le(FDe,1),it,388,0,[Lde,XT,k4])))}function elt(){elt=U,fTt=Kr((xA(),he(le(eIe,1),it,392,0,[ZDe,Ide,OB])))}function tlt(){tlt=U,UTt=Kr((LN(),he(le(AIe,1),it,393,0,[zW,SIe,_Ie])))}function nlt(){nlt=U,fCt=Kr((AV(),he(le(GIe,1),it,300,0,[nge,UIe,VIe])))}function rlt(){rlt=U,dCt=Kr((WV(),he(le(KIe,1),it,445,0,[RB,VW,rge])))}function ilt(){ilt=U,pCt=Kr((sU(),he(le(gCt,1),it,456,0,[ige,age,sge])))}function slt(){slt=U,vCt=Kr((qV(),he(le(XIe,1),it,394,0,[YIe,uge,WIe])))}function alt(){alt=U,$Ct=Kr((tV(),he(le(pOe,1),it,439,0,[gge,gOe,dOe])))}function olt(){olt=U,_Et=Kr((Iw(),he(le(SEt,1),it,464,0,[DB,oM,MW])))}function clt(){clt=U,Y6t=Kr((Bl(),he(le(W6t,1),it,471,0,[Fd,Bb,v0])))}function ult(){ult=U,K6t=Kr((t1(),he(le(s4,1),it,237,0,[Gc,$u,Kc])))}function llt(){llt=U,Q6t=Kr((ol(),he(le(X6t,1),it,472,0,[a1,Fb,w0])))}function hlt(){hlt=U,B6t=Kr((Fl(),he(le(oc,1),it,108,0,[y_e,Ec,i4])))}function flt(){flt=U,m8t=Kr((lA(),he(le(dAe,1),it,391,0,[t1e,e1e,n1e])))}function dlt(){dlt=U,QSt=Kr((rp(),he(le(YNe,1),it,346,0,[oY,A2,DM])))}function glt(){glt=U,VCt=Kr((PN(),he(le(pge,1),it,444,0,[WW,YW,XW])))}function plt(){plt=U,KSt=Kr((F1(),he(le(FNe,1),it,278,0,[nC,_4,rC])))}function blt(){blt=U,h_t=Kr((dx(),he(le(nPe,1),it,280,0,[tPe,L4,dY])))}function P1(e,t){return!e.o&&(e.o=new xl((su(),Cg),L2,e,0)),Kce(e.o,t)}function fvn(e,t){var n;e.C&&(n=l(Qo(e.b,t),127).n,n.d=e.C.d,n.a=e.C.a)}function A6e(e){var t,n,r,a;a=e.d,t=e.a,n=e.b,r=e.c,e.d=n,e.a=r,e.b=a,e.c=t}function dvn(e){return!e.g&&(e.g=new MS),!e.g.b&&(e.g.b=new fQe(e)),e.g.b}function iN(e){return!e.g&&(e.g=new MS),!e.g.c&&(e.g.c=new pQe(e)),e.g.c}function gvn(e){return!e.g&&(e.g=new MS),!e.g.d&&(e.g.d=new dQe(e)),e.g.d}function pvn(e){return!e.g&&(e.g=new MS),!e.g.a&&(e.g.a=new gQe(e)),e.g.a}function bvn(e,t,n,r){return n&&(r=n.Rh(t,ms(n.Dh(),e.c.uk()),null,r)),r}function mvn(e,t,n,r){return n&&(r=n.Th(t,ms(n.Dh(),e.c.uk()),null,r)),r}function Ooe(e,t,n,r){var a;return a=We(Vr,di,28,t+1,15,1),xAn(a,e,t,n,r),a}function We(e,t,n,r,a,o){var f;return f=zdt(a,r),a!=10&&he(le(e,o),t,n,a,f),f}function vvn(e,t,n){var r,a;for(a=new mE(t,e),r=0;rn||t=0?e.Lh(n,!0,!0):Hw(e,t,!0)}function Pvn(e,t,n){var r;return r=w0t(e,t,n),e.b=new TV(r.c.length),Q9e(e,r)}function Bvn(e){if(e.b<=0)throw ue(new _c);return--e.b,e.a-=e.c.c,pt(e.a)}function Fvn(e){var t;if(!e.a)throw ue(new Lat);return t=e.a,e.a=ds(e.a),t}function Rvn(e){for(;!e.a;)if(!tit(e.c,new ZS(e)))return!1;return!0}function cx(e){var t;return Xr(e),De(e,204)?(t=l(e,204),t):new w8(e)}function jvn(e){ZH(),l(e.of((pi(),S4)),181).Fc((Rl(),nF)),e.qf($ge,null)}function ZH(){ZH=U,pSt=new l$,mSt=new h$,bSt=_yn((pi(),$ge),pSt,Ub,mSt)}function eV(){eV=U,TIe=new G3e("LEAF_NUMBER",0),Qde=new G3e("NODE_SIZE",1)}function Roe(e){e.a=We(Vr,di,28,e.b+1,15,1),e.c=We(Vr,di,28,e.b,15,1),e.d=0}function $vn(e,t){e.a.Ne(t.d,e.b)>0&&(vt(e.c,new L4e(t.c,t.d,e.d)),e.b=t.d)}function R6e(e,t){if(e.g==null||t>=e.i)throw ue(new Vse(t,e.i));return e.g[t]}function ylt(e,t,n){if(EE(e,n),n!=null&&!e.fk(n))throw ue(new Rie);return n}function joe(e,t){return gN(t)!=10&&he(bh(t),t.Sm,t.__elementTypeId$,gN(t),e),e}function nE(e,t,n,r){var a;r=(Ew(),r||d_e),a=e.slice(t,n),l9e(a,e,t,n,-t,r)}function sf(e,t,n,r,a){return t<0?Hw(e,n,r):l(n,69).wk().yk(e,e.hi(),t,r,a)}function zvn(e,t){return Yi(ze(Ge(Q(e,(ft(),l3)))),ze(Ge(Q(t,l3))))}function xlt(){xlt=U,M6t=Kr((rE(),he(le(fK,1),it,304,0,[O0e,N0e,P0e,B0e])))}function rE(){rE=U,O0e=new oq("All",0),N0e=new hnt,P0e=new ynt,B0e=new lnt}function Bl(){Bl=U,Fd=new pse(Mx,0),Bb=new pse(cT,1),v0=new pse(Dx,2)}function klt(){klt=U,zU(),GPe=gs,vAt=ia,KPe=new pa(gs),wAt=new pa(ia)}function Elt(){Elt=U,k7t=Kr((Pw(),he(le(x7t,1),it,417,0,[iB,rB,V0e,U0e])))}function Tlt(){Tlt=U,_7t=Kr((NA(),he(le(S7t,1),it,406,0,[uB,bK,mK,lB])))}function Clt(){Clt=U,T7t=Kr((bx(),he(le(E7t,1),it,332,0,[aB,sB,oB,cB])))}function Slt(){Slt=U,I8t=Kr((Km(),he(le(mAe,1),it,389,0,[c4,bAe,o1e,c1e])))}function _lt(){_lt=U,S8t=Kr((wE(),he(le(C8t,1),it,416,0,[s3,o4,a4,M6])))}function Alt(){Alt=U,nxt=Kr((R1(),he(le(txt,1),it,421,0,[Vx,MT,DT,b1e])))}function Llt(){Llt=U,U8t=Kr((IV(),he(le(V8t,1),it,371,0,[p1e,HK,VK,pB])))}function Mlt(){Mlt=U,eEt=Kr((By(),he(le(mde,1),it,203,0,[_W,bde,G6,U6])))}function Dlt(){Dlt=U,rEt=Kr((Ed(),he(le(SDe,1),it,284,0,[E2,CDe,yde,xde])))}function cN(){cN=U,xLe=new B3e(Id,0),JK=new B3e("IMPROVE_STRAIGHTNESS",1)}function Ilt(e,t){var n,r;return r=t/e.c.Rd().gc()|0,n=t%e.c.Rd().gc(),ox(e,r,n)}function Olt(e){var t;if(e.nl())for(t=e.i-1;t>=0;--t)Oe(e,t);return a6e(e)}function j6e(e){var t,n;if(!e.b)return null;for(n=e.b;t=n.a[0];)n=t;return n}function Nlt(e){var t,n;if(!e.b)return null;for(n=e.b;t=n.a[1];)n=t;return n}function qvn(e){return De(e,180)?""+l(e,180).a:e==null?null:xc(e)}function Hvn(e){return De(e,180)?""+l(e,180).a:e==null?null:xc(e)}function Plt(e,t){if(t.a)throw ue(new Ac(e3t));na(e.a,t),t.a=e,!e.j&&(e.j=t)}function $6e(e,t){Dq.call(this,t.zd(),t.yd()&-16449),nr(e),this.a=e,this.c=t}function Vvn(e,t){return new wae(t,dw(Ja(t.e),t.f.a+e,t.f.b+e),(Hn(),!1))}function Uvn(e,t){return jk(),vt(e,new ca(t,pt(t.e.c.length+t.g.c.length)))}function Gvn(e,t){return jk(),vt(e,new ca(t,pt(t.e.c.length+t.g.c.length)))}function Blt(){Blt=U,hCt=Kr((uU(),he(le(HIe,1),it,354,0,[tge,zIe,qIe,$Ie])))}function Flt(){Flt=U,PTt=Kr((kA(),he(le(yIe,1),it,353,0,[Vde,jW,Hde,qde])))}function Rlt(){Rlt=U,lTt=Kr((wx(),he(le(qDe,1),it,405,0,[NW,lM,hM,fM])))}function jlt(){jlt=U,WSt=Kr((ip(),he(le(Vge,1),it,223,0,[Hge,JB,iC,s9])))}function $lt(){$lt=U,ZSt=Kr((Ih(),he(le(JSt,1),it,291,0,[eF,kg,Gb,ZB])))}function zlt(){zlt=U,u_t=Kr((mh(),he(le(BM,1),it,386,0,[iF,Cv,rF,A4])))}function qlt(){qlt=U,d_t=Kr((VV(),he(le(cPe,1),it,320,0,[Kge,sPe,oPe,aPe])))}function Hlt(){Hlt=U,b_t=Kr((NV(),he(le(p_t,1),it,415,0,[Wge,lPe,uPe,hPe])))}function tV(){tV=U,gge=new jse(vyt,0),gOe=new jse(cCe,1),dOe=new jse(Id,2)}function Sy(e,t,n,r,a){return nr(e),nr(t),nr(n),nr(r),nr(a),new h5e(e,t,r)}function Vlt(e,t){var n;return n=l(ax(e.e,t),400),n?($4e(n),n.e):null}function al(e,t){var n;return n=gc(e,t,0),n==-1?!1:(t2(e,n),!0)}function Ult(e,t,n){var r;return fb(e),r=new on,r.a=t,e.a.Nb(new Cet(r,n)),r.a}function Kvn(e){var t;return fb(e),t=We(Na,Zo,28,0,15,1),A5(e.a,new E8(t)),t}function z6e(e){var t;if(!tce(e))throw ue(new _c);return e.e=1,t=e.d,e.d=null,t}function r2(e){var t;return wc(e)&&(t=0-e,!isNaN(t))?t:mb(xE(e))}function gc(e,t,n){for(;n=0?rU(e,n,!0,!0):Hw(e,t,!0)}function H6e(e){var t;return t=jm(Kn(e,32)),t==null&&(Ku(e),t=jm(Kn(e,32))),t}function V6e(e){var t;return e.Oh()||(t=yr(e.Dh())-e.ji(),e.$h().Mk(t)),e.zh()}function Qlt(e,t){H_e=new Ot,C7t=t,RL=e,l(RL.b,68),D6e(RL,H_e,null),fvt(RL)}function lA(){lA=U,t1e=new mse("XY",0),e1e=new mse("X",1),n1e=new mse("Y",2)}function ol(){ol=U,a1=new bse("TOP",0),Fb=new bse(cT,1),w0=new bse(xEe,2)}function ep(){ep=U,wB=new Ese(Id,0),F6=new Ese("TOP",1),Ux=new Ese(xEe,2)}function dN(){dN=U,kde=new R3e("INPUT_ORDER",0),Ede=new R3e("PORT_DEGREE",1)}function iE(){iE=U,WSe=qu(eh,eh,524287),g6t=qu(0,0,SP),YSe=Loe(1),Loe(2),XSe=Loe(0)}function Voe(e){var t;return e.d!=e.r&&(t=Of(e),e.e=!!t&&t.lk()==g5t,e.d=t),e.e}function Uoe(e,t,n){var r;return r=e.g[t],R_(e,t,e.Zi(t,n)),e.Ri(t,n,r),e.Ni(),r}function sV(e,t){var n;return n=e.dd(t),n>=0?(e.gd(n),!0):!1}function Goe(e,t){var n;for(Xr(e),Xr(t),n=!1;t.Ob();)n=n|e.Fc(t.Pb());return n}function B1(e,t){var n;return n=l(cr(e.e,t),400),n?(Int(e,n),n.e):null}function Jlt(e){var t,n;return t=e/60|0,n=e%60,n==0?""+t:""+t+":"+(""+n)}function _y(e,t){var n=e.a[t],r=(vce(),_0e)[typeof n];return r?r(n):Z7e(typeof n)}function Dc(e,t){var n,r;return xb(e),r=new C6e(t,e.a),n=new iit(r),new bn(e,n)}function Koe(e){var t;return t=e.b.c.length==0?null:jt(e.b,0),t!=null&&rce(e,0),t}function Qvn(e,t){var n,r,a;a=t.c.i,n=l(cr(e.f,a),60),r=n.d.c-n.e.c,k7e(t.a,r,0)}function U6e(e,t){var n;for(++e.d,++e.c[t],n=t+1;n=0;)++t[0]}function Jvn(e,t){Uu(e,t==null||Gq((nr(t),t))||isNaN((nr(t),t))?0:(nr(t),t))}function Zvn(e,t){Gu(e,t==null||Gq((nr(t),t))||isNaN((nr(t),t))?0:(nr(t),t))}function ewn(e,t){Dw(e,t==null||Gq((nr(t),t))||isNaN((nr(t),t))?0:(nr(t),t))}function twn(e,t){Mw(e,t==null||Gq((nr(t),t))||isNaN((nr(t),t))?0:(nr(t),t))}function nwn(e,t,n){return z8(new lt(n.e.a+n.f.a/2,n.e.b+n.f.b/2),e)==(nr(t),t)}function rwn(e,t){return De(t,102)&&l(t,19).Bb&Io?new Use(t,e):new mE(t,e)}function iwn(e,t){return De(t,102)&&l(t,19).Bb&Io?new Use(t,e):new mE(t,e)}function gN(e){return e.__elementTypeCategory$==null?10:e.__elementTypeCategory$}function tht(e,t){return t==(gae(),gae(),_6t)?e.toLocaleLowerCase():e.toLowerCase()}function nht(e){if(!e.e)throw ue(new _c);return e.c=e.a=e.e,e.e=e.e.e,--e.d,e.a.f}function G6e(e){if(!e.c)throw ue(new _c);return e.e=e.a=e.c,e.c=e.c.c,++e.d,e.a.f}function rht(e){var t;for(++e.a,t=e.c.a.length;e.ae.a[r]&&(r=n);return r}function iht(e){var t;return t=l(Q(e,(ft(),c3)),313),t?t.a==e:!1}function sht(e){var t;return t=l(Q(e,(ft(),c3)),313),t?t.i==e:!1}function aht(){aht=U,x8t=Kr((uo(),he(le(gAe,1),it,367,0,[y0,vg,bu,_u,mc])))}function oht(){oht=U,ixt=Kr((Ry(),he(le(rxt,1),it,375,0,[bB,KK,WK,GK,UK])))}function cht(){cht=U,pxt=Kr((l2(),he(le(mLe,1),it,348,0,[A1e,bLe,L1e,BT,PT])))}function uht(){uht=U,tEt=Kr((OA(),he(le(wDe,1),it,323,0,[vDe,vde,wde,rM,iM])))}function lht(){lht=U,Axt=Kr((hf(),he(le(WLe,1),it,171,0,[EB,YL,$b,XL,d4])))}function hht(){hht=U,HTt=Kr((bU(),he(le(qTt,1),it,368,0,[Yde,Gde,Xde,Kde,Wde])))}function fht(){fht=U,HCt=Kr((VA(),he(le(qCt,1),it,373,0,[Q6,e9,xM,yM,zB])))}function dht(){dht=U,YCt=Kr((XN(),he(le(TOe,1),it,324,0,[xOe,wge,EOe,yge,kOe])))}function ght(){ght=U,GSt=Kr((Js(),he(le(LM,1),it,88,0,[J1,vc,uc,Q1,wf])))}function pht(){pht=U,vSt=Kr((r1(),he(le(xg,1),it,170,0,[Pn,ha,zd,yv,S2])))}function bht(){bht=U,t_t=Kr((t6(),he(le(OM,1),it,256,0,[Kb,tF,XNe,IM,QNe])))}function mht(){mht=U,i_t=Kr((Ct(),he(le(Oo,1),au,64,0,[Pc,Qn,ar,Dr,er])))}function aV(){aV=U,E_e=new A3e("BY_SIZE",0),$0e=new A3e("BY_SIZE_AND_SHAPE",1)}function oV(){oV=U,Q0e=new D3e("EADES",0),yK=new D3e("FRUCHTERMAN_REINGOLD",1)}function pN(){pN=U,XK=new P3e("READING_DIRECTION",0),vLe=new P3e("ROTATION",1)}function hA(){hA=U,L8t=new nI,M8t=new $J,_8t=new vm,A8t=new hu,D8t=new zJ}function vht(e){this.b=new bt,this.a=new bt,this.c=new bt,this.d=new bt,this.e=e}function wht(e){this.g=e,this.f=new bt,this.a=b.Math.min(this.g.c.c,this.g.d.c)}function yht(e,t,n){Vq.call(this),Y6e(this),this.a=e,this.c=n,this.b=t.d,this.f=t.e}function lwn(e,t,n){var r,a;for(a=new G(n);a.a=0&&t0?t-1:t,ZJe(Fun(Vht(B4e(new L8,n),e.n),e.j),e.k)}function sc(e){var t,n;n=(t=new qie,t),qr((!e.q&&(e.q=new nt(Uf,e,11,10)),e.q),n)}function K6e(e){return(e.i&2?"interface ":e.i&1?"":"class ")+(Gg(e),e.o)}function cV(e){return iu(e,Ii)>0?Ii:iu(e,lo)<0?lo:Yr(e)}function Ay(e){return e<3?(Mh(e,Pwt),e+1):e=-.01&&e.a<=H1&&(e.a=0),e.b>=-.01&&e.b<=H1&&(e.b=0),e}function Y5(e){h6();var t,n;for(n=hCe,t=0;tn&&(n=e[t]);return n}function Tht(e,t){var n;if(n=oP(e.Dh(),t),!n)throw ue(new Yn(Ob+t+$fe));return n}function Ly(e,t){var n;for(n=e;ds(n);)if(n=ds(n),n==t)return!0;return!1}function xwn(e,t){var n,r,a;for(r=t.a.ld(),n=l(t.a.md(),16).gc(),a=0;ae||e>t)throw ue(new t3e("fromIndex: 0, toIndex: "+e+uEe+t))}function Lw(e){if(e<0)throw ue(new Yn("Illegal Capacity: "+e));this.g=this.aj(e)}function W6e(e,t){return A1(),f0(Ab),b.Math.abs(e-t)<=Ab||e==t||isNaN(e)&&isNaN(t)}function Xoe(e,t){var n,r,a,o;for(r=e.d,a=0,o=r.length;a0&&(e.a/=t,e.b/=t),e}function Ah(e){var t;return e.w?e.w:(t=dbn(e),t&&!t.Vh()&&(e.w=t),t)}function sE(e,t){var n,r;r=e.a,n=m4n(e,t,null),r!=t&&!e.e&&(n=ZE(e,t,n)),n&&n.oj()}function Lht(e,t,n){var r,a;r=t;do a=ze(e.p[r.p])+n,e.p[r.p]=a,r=e.a[r.p];while(r!=t)}function Mht(e,t,n){var r=function(){return e.apply(r,arguments)};return t.apply(r,n),r}function Awn(e){var t;return e==null?null:(t=l(e,195),$xn(t,t.length))}function Oe(e,t){if(e.g==null||t>=e.i)throw ue(new Vse(t,e.i));return e.Wi(t,e.g[t])}function Lwn(e,t){Cn();var n,r;for(r=new bt,n=0;n=14&&t<=16))),e}function Gr(e,t){var n;return nr(t),n=e[":"+t],BO(!!n,"Enum constant undefined: "+t),n}function Fr(e,t,n,r,a,o){var f;return f=Gae(e,t),Uht(n,f),f.i=a?8:0,f.f=r,f.e=a,f.g=o,f}function Q6e(e,t,n,r,a){this.d=t,this.k=r,this.f=a,this.o=-1,this.p=1,this.c=e,this.a=n}function J6e(e,t,n,r,a){this.d=t,this.k=r,this.f=a,this.o=-1,this.p=2,this.c=e,this.a=n}function Z6e(e,t,n,r,a){this.d=t,this.k=r,this.f=a,this.o=-1,this.p=6,this.c=e,this.a=n}function e7e(e,t,n,r,a){this.d=t,this.k=r,this.f=a,this.o=-1,this.p=7,this.c=e,this.a=n}function t7e(e,t,n,r,a){this.d=t,this.j=r,this.e=a,this.o=-1,this.p=4,this.c=e,this.a=n}function Ght(e,t){var n,r,a,o;for(r=t,a=0,o=r.length;a=0))throw ue(new Yn("tolerance ("+e+") must be >= 0"));return e}function Wht(e,t){var n;return De(t,44)?e.c.Mc(t):(n=Kce(e,t),YV(e,t),n)}function Jo(e,t,n){return Gm(e,t),Fu(e,n),i2(e,0),My(e,1),u2(e,!0),c2(e,!0),e}function mN(e,t){var n;if(n=e.gc(),t<0||t>n)throw ue(new my(t,n));return new f4e(e,t)}function bV(e,t){e.b=b.Math.max(e.b,t.d),e.e+=t.r+(e.a.c.length==0?0:e.c),vt(e.a,t)}function Yht(e){gy(e.c>=0),H5n(e.d,e.c)<0&&(e.a=e.a-1&e.d.a.length-1,e.b=e.d.c),e.c=-1}function mV(e){var t,n;for(n=e.c.Cc().Kc();n.Ob();)t=l(n.Pb(),16),t.$b();e.c.$b(),e.d=0}function jwn(e){var t,n,r,a;for(n=e.a,r=0,a=n.length;r=0}function c7e(e,t){e.r>0&&e.c0&&e.g!=0&&c7e(e.i,t/e.r*e.i.d))}function u7e(e,t){var n;n=e.c,e.c=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,1,n,e.c))}function Zoe(e,t){var n;n=e.c,e.c=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,4,n,e.c))}function fE(e,t){var n;n=e.k,e.k=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,2,n,e.k))}function ece(e,t){var n;n=e.D,e.D=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,2,n,e.D))}function wV(e,t){var n;n=e.f,e.f=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,8,n,e.f))}function yV(e,t){var n;n=e.i,e.i=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,7,n,e.i))}function l7e(e,t){var n;n=e.a,e.a=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,8,n,e.a))}function h7e(e,t){var n;n=e.b,e.b=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,0,n,e.b))}function f7e(e,t){var n;n=e.b,e.b=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,0,n,e.b))}function d7e(e,t){var n;n=e.c,e.c=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,1,n,e.c))}function g7e(e,t){var n;n=e.d,e.d=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,1,n,e.d))}function Gwn(e,t,n){var r;e.b=t,e.a=n,r=(e.a&512)==512?new gJe:new J$,e.c=aSn(r,e.b,e.a)}function oft(e,t){return up(e.e,t)?(Fo(),Voe(t)?new nH(t,e):new yO(t,e)):new Ptt(t,e)}function Kwn(e){var t,n;return 0>e?new b3e:(t=e+1,n=new wut(t,e),new Uye(null,n))}function Wwn(e,t){Cn();var n;return n=new N8(1),Ia(e)?rc(n,e,t):ju(n.f,e,t),new tr(n)}function Ywn(e,t){var n,r;return n=e.c,r=t.e[e.p],r>0?l(jt(n.a,r-1),10):null}function Xwn(e,t){var n,r;return n=e.o+e.p,r=t.o+t.p,nt?(t<<=1,t>0?t:rL):t}function tce(e){switch(Cye(e.e!=3),e.e){case 2:return!1;case 0:return!0}return svn(e)}function uft(e,t){var n;return De(t,8)?(n=l(t,8),e.a==n.a&&e.b==n.b):!1}function Jwn(e,t){var n;n=new Ot,l(t.b,68),l(t.b,68),l(t.b,68),Vu(t.a,new k4e(e,n,t))}function lft(e,t){var n,r;for(r=t.vc().Kc();r.Ob();)n=l(r.Pb(),44),GN(e,n.ld(),n.md())}function p7e(e,t){var n;n=e.d,e.d=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,11,n,e.d))}function xV(e,t){var n;n=e.j,e.j=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,13,n,e.j))}function b7e(e,t){var n;n=e.b,e.b=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,21,n,e.b))}function Zwn(e,t){(UH(),G1?null:t.c).length==0&&Srt(t,new Dt),rc(e.a,G1?null:t.c,t)}function e3n(e,t){t.Ug("Hierarchical port constraint processing",1),v6n(e),RIn(e),t.Vg()}function Ow(){Ow=U,o3=new vse("START",0),Rb=new vse("MIDDLE",1),a3=new vse("END",2)}function kV(){kV=U,$W=new U3e("P1_NODE_PLACEMENT",0),X6=new U3e("P2_EDGE_ROUTING",1)}function bb(){bb=U,Hx=new Ui(NEe),EK=new Ui(C3t),$L=new Ui(S3t),hB=new Ui(_3t)}function Nw(e){var t;return pae(e.f.g,e.d),mr(e.b),e.c=e.a,t=l(e.a.Pb(),44),e.b=L7e(e),t}function m7e(e){var t;return e.b==null?(Wp(),Wp(),dF):(t=e.ul()?e.tl():e.sl(),t)}function hft(e,t){var n;return n=t==null?-1:gc(e.b,t,0),n<0?!1:(rce(e,n),!0)}function d0(e,t){var n;return nr(t),n=t.g,e.b[n]?!1:(Ts(e.b,n,t),++e.c,!0)}function EV(e,t){var n,r;return n=1-t,r=e.a[n],e.a[n]=r.a[t],r.a[t]=e,e.b=!0,r.b=!1,r}function t3n(e,t){var n,r;for(r=t.Kc();r.Ob();)n=l(r.Pb(),272),e.b=!0,na(e.e,n),n.b=e}function n3n(e,t){var n,r;return n=l(Q(e,(Nt(),w4)),8),r=l(Q(t,w4),8),Yi(n.b,r.b)}function nce(e,t,n){var r,a,o;return o=t>>5,a=t&31,r=va(ub(e.n[n][o],Yr(l0(a,1))),3),r}function fft(e,t,n){var r,a,o;for(o=e.a.length-1,a=e.b,r=0;r0?1:0:(!e.c&&(e.c=XO(Zc(e.f))),e.c).e}function xft(e,t){t?e.B==null&&(e.B=e.D,e.D=null):e.B!=null&&(e.D=e.B,e.B=null)}function a3n(e,t){return wE(),e==s3&&t==o4||e==o4&&t==s3||e==M6&&t==a4||e==a4&&t==M6}function o3n(e,t){return wE(),e==s3&&t==a4||e==s3&&t==M6||e==o4&&t==M6||e==o4&&t==a4}function kft(e,t){return A1(),f0(H1),b.Math.abs(0-t)<=H1||t==0||isNaN(0)&&isNaN(t)?0:e/t}function Eft(e,t){return ze(Ge(fh(ON(fc(new bn(null,new kn(e.c.b,16)),new AYe(e)),t))))}function x7e(e,t){return ze(Ge(fh(ON(fc(new bn(null,new kn(e.c.b,16)),new _Ye(e)),t))))}function c3n(){return Ho(),he(le(F1e,1),it,259,0,[eW,vf,UL,tW,$T,B6,GL,RT,jT,nW])}function u3n(){return Nf(),he(le(TDe,1),it,243,0,[AW,AB,LB,xDe,kDe,yDe,EDe,LW,v3,x4])}function l3n(e,t){var n;t.Ug("General Compactor",1),n=p5n(l(at(e,(Sb(),Zde)),393)),n.Cg(e)}function h3n(e,t){var n,r;return n=l(at(e,(Sb(),qW)),17),r=l(at(t,qW),17),ru(n.a,r.a)}function k7e(e,t,n){var r,a;for(a=Rr(e,0);a.b!=a.d.c;)r=l(Br(a),8),r.a+=t,r.b+=n;return e}function gA(e,t,n){var r;for(r=e.b[n&e.f];r;r=r.b)if(n==r.a&&yd(t,r.g))return r;return null}function pA(e,t,n){var r;for(r=e.c[n&e.f];r;r=r.d)if(n==r.f&&yd(t,r.i))return r;return null}function f3n(e,t,n){var r,a,o;for(r=0,a=0;a>>31;r!=0&&(e[n]=r)}function oce(e,t,n,r,a,o){var f;this.c=e,f=new bt,txe(e,f,t,e.b,n,r,a,o),this.a=new Ua(f,0)}function Tft(){this.c=new Wz(0),this.b=new Wz(lCe),this.d=new Wz(hyt),this.a=new Wz(Lhe)}function of(e,t,n,r,a,o,f){Ur.call(this,e,t),this.d=n,this.e=r,this.c=a,this.b=o,this.a=O1(f)}function Os(e,t,n,r,a,o,f,g,w,E,C,L,B){return Lpt(e,t,n,r,a,o,f,g,w,E,C,L,B),$ce(e,!1),e}function d3n(e){return e.b.c.i.k==(Zn(),Us)?l(Q(e.b.c.i,(ft(),zi)),12):e.b.c}function Cft(e){return e.b.d.i.k==(Zn(),Us)?l(Q(e.b.d.i,(ft(),zi)),12):e.b.d}function g3n(e){var t;return t=jH(e),cw(t.a,0)?(Jz(),Jz(),A6t):(Jz(),new art(t.b))}function cce(e){var t;return t=e6e(e),cw(t.a,0)?(cy(),cy(),I0e):(cy(),new sae(t.b))}function uce(e){var t;return t=e6e(e),cw(t.a,0)?(cy(),cy(),I0e):(cy(),new sae(t.c))}function Sft(e){switch(e.g){case 2:return Ct(),er;case 4:return Ct(),ar;default:return e}}function _ft(e){switch(e.g){case 1:return Ct(),Dr;case 3:return Ct(),Qn;default:return e}}function Aft(e){switch(e.g){case 0:return new Mne;case 1:return new Dne;default:return null}}function lx(){lx=U,g1e=new vs("edgelabelcenterednessanalysis.includelabel",(Hn(),Pb))}function E7e(){E7e=U,CEt=Td(Ytt(fi(fi(new Xs,(uo(),bu),(vo(),PK)),_u,MK),mc),NK)}function Lft(){Lft=U,LEt=Td(Ytt(fi(fi(new Xs,(uo(),bu),(vo(),PK)),_u,MK),mc),NK)}function lce(){lce=U,qM=new uJe,npe=he(le(dl,1),S6,179,0,[]),X_t=he(le(Uf,1),LSe,62,0,[])}function dE(){dE=U,dB=new I3e("TO_INTERNAL_LTR",0),h1e=new I3e("TO_INPUT_DIRECTION",1)}function kl(){kl=U,EAe=new K2,xAe=new J3,kAe=new HJ,yAe=new wm,TAe=new VJ,CAe=new UJ}function p3n(e,t){t.Ug(q3t,1),S8e(Zun(new e_((g_(),new Jae(e,!1,!1,new cS))))),t.Vg()}function b3n(e,t,n){n.Ug("DFS Treeifying phase",1),O5n(e,t),DCn(e,t),e.a=null,e.b=null,n.Vg()}function vN(e,t){return Hn(),Ia(e)?E6e(e,ei(t)):fy(e)?Nae(e,Ge(t)):hy(e)?agn(e,Bt(t)):e.Fd(t)}function bA(e,t){var n,r;for(nr(t),r=t.vc().Kc();r.Ob();)n=l(r.Pb(),44),e.zc(n.ld(),n.md())}function m3n(e,t,n){var r;for(r=n.Kc();r.Ob();)if(!qH(e,t,r.Pb()))return!1;return!0}function v3n(e,t,n,r,a){var o;return n&&(o=ms(t.Dh(),e.c),a=n.Rh(t,-1-(o==-1?r:o),null,a)),a}function w3n(e,t,n,r,a){var o;return n&&(o=ms(t.Dh(),e.c),a=n.Th(t,-1-(o==-1?r:o),null,a)),a}function Mft(e){var t;if(e.b==-2){if(e.e==0)t=-1;else for(t=0;e.a[t]==0;t++);e.b=t}return e.b}function y3n(e){if(nr(e),e.length==0)throw ue(new gd("Zero length BigInteger"));S_n(this,e)}function T7e(e){this.i=e.gc(),this.i>0&&(this.g=this.aj(this.i+(this.i/8|0)+1),e.Qc(this.g))}function Dft(e,t,n){this.g=e,this.d=t,this.e=n,this.a=new bt,Ikn(this),Cn(),Vs(this.a,null)}function C7e(e,t){t.q=e,e.d=b.Math.max(e.d,t.r),e.b+=t.d+(e.a.c.length==0?0:e.c),vt(e.a,t)}function gE(e,t){var n,r,a,o;return a=e.c,n=e.c+e.b,o=e.d,r=e.d+e.a,t.a>a&&t.ao&&t.ba?n=a:Xn(t,n+1),e.a=tf(e.a,0,t)+(""+r)+w5e(e.a,n)}function $ft(e,t){e.a=bo(e.a,1),e.c=b.Math.min(e.c,t),e.b=b.Math.max(e.b,t),e.d=bo(e.d,t)}function _3n(e,t){return t1||e.Ob())return++e.a,e.g=0,t=e.i,e.Ob(),t;throw ue(new _c)}function Vft(e){switch(e.a.g){case 1:return new Yet;case 3:return new Ydt;default:return new nie}}function _7e(e,t){switch(t){case 1:return!!e.n&&e.n.i!=0;case 2:return e.k!=null}return Z5e(e,t)}function Zc(e){return _P>22),a=e.h+t.h+(r>>22),qu(n&eh,r&eh,a&hp)}function Jft(e,t){var n,r,a;return n=e.l-t.l,r=e.m-t.m+(n>>22),a=e.h-t.h+(r>>22),qu(n&eh,r&eh,a&hp)}function W3n(e){var t,n;for(zDn(e),n=new G(e.d);n.ar)throw ue(new my(t,r));return e.Si()&&(n=bot(e,n)),e.Ei(t,n)}function yE(e,t,n,r,a){var o,f;for(f=n;f<=a;f++)for(o=t;o<=r;o++)r6(e,o,f)||FU(e,o,f,!0,!1)}function cyn(e){h6();var t,n,r;for(n=We(Ea,dt,8,2,0,1),r=0,t=0;t<2;t++)r+=.5,n[t]=t7n(r,e);return n}function xE(e){var t,n,r;return t=~e.l+1&eh,n=~e.m+(t==0?1:0)&eh,r=~e.h+(t==0&&n==0?1:0)&hp,qu(t,n,r)}function P7e(e){var t;if(e<0)return lo;if(e==0)return 0;for(t=rL;!(t&e);t>>=1);return t}function mce(e,t,n){return e>=128?!1:e<64?I_(va(l0(1,e),n),0):I_(va(l0(1,e-64),t),0)}function _N(e,t,n){return n==null?(!e.q&&(e.q=new Pr),ax(e.q,t)):(!e.q&&(e.q=new Pr),ki(e.q,t,n)),e}function rt(e,t,n){return n==null?(!e.q&&(e.q=new Pr),ax(e.q,t)):(!e.q&&(e.q=new Pr),ki(e.q,t,n)),e}function u0t(e){var t,n;return n=new KH,pc(n,e),rt(n,(bb(),Hx),e),t=new Pr,FAn(e,n,t),hDn(e,n,t),n}function l0t(e){var t,n;return t=e.t-e.k[e.o.p]*e.d+e.j[e.o.p]>e.f,n=e.u+e.e[e.o.p]*e.d>e.f*e.s*e.d,t||n}function h0t(e,t){var n,r,a,o;for(n=!1,r=e.a[t].length,o=0;o=0,"Negative initial capacity"),BO(t>=0,"Non-positive load factor"),Nl(this)}function lyn(e,t,n,r,a){var o,f;if(f=e.length,o=n.length,t<0||r<0||a<0||t+a>f||r+a>o)throw ue(new _we)}function j7e(e,t){Cn();var n,r,a,o,f;for(f=!1,r=t,a=0,o=r.length;a1||t>=0&&e.b<3)}function yce(e){var t,n,r;t=~e.l+1&eh,n=~e.m+(t==0?1:0)&eh,r=~e.h+(t==0&&n==0?1:0)&hp,e.l=t,e.m=n,e.h=r}function q7e(e){Cn();var t,n,r;for(r=1,n=e.Kc();n.Ob();)t=n.Pb(),r=31*r+(t!=null?es(t):0),r=r|0;return r}function pyn(e,t,n,r,a){var o;return o=D9e(e,t),n&&yce(o),a&&(e=c7n(e,t),r?Nb=xE(e):Nb=qu(e.l,e.m,e.h)),o}function x0t(e,t,n){e.g=Rue(e,t,(Ct(),ar),e.b),e.d=Rue(e,n,ar,e.b),!(e.g.c==0||e.d.c==0)&&Jgt(e)}function k0t(e,t,n){e.g=Rue(e,t,(Ct(),er),e.j),e.d=Rue(e,n,er,e.j),!(e.g.c==0||e.d.c==0)&&Jgt(e)}function H7e(e,t){switch(t){case 7:return!!e.e&&e.e.i!=0;case 8:return!!e.d&&e.d.i!=0}return _8e(e,t)}function byn(e,t){switch(t.g){case 0:De(e.b,641)||(e.b=new jft);break;case 1:De(e.b,642)||(e.b=new Rit)}}function E0t(e){switch(e.g){case 0:return new One;default:throw ue(new Yn(FG+(e.f!=null?e.f:""+e.g)))}}function T0t(e){switch(e.g){case 0:return new gl;default:throw ue(new Yn(FG+(e.f!=null?e.f:""+e.g)))}}function myn(e,t,n){return!_k(Fi(new bn(null,new kn(e.c,16)),new Wl(new ltt(t,n)))).Bd((Am(),zx))}function C0t(e,t){return z8(BE(l(Q(t,(Hc(),y3)),88)),new lt(e.c.e.a-e.b.e.a,e.c.e.b-e.b.e.b))<=0}function vyn(e,t){for(;e.g==null&&!e.c?H5e(e):e.g==null||e.i!=0&&l(e.g[e.i-1],51).Ob();)kln(t,CU(e))}function Um(e){var t,n;for(n=new G(e.a.b);n.ar?1:0}function xyn(e){return vt(e.c,(hx(),gSt)),W6e(e.a,ze(Ge(It((Gce(),TW)))))?new Hne:new OXe(e)}function kyn(e){for(;!e.d||!e.d.Ob();)if(e.b&&!l_(e.b))e.d=l(X8(e.b),51);else return null;return e.d}function U7e(e){switch(e.g){case 1:return hyt;default:case 2:return 0;case 3:return Lhe;case 4:return lCe}}function Eyn(){Di();var e;return cpe||(e=Hhn(_b("M",!0)),e=oH(_b("M",!1),e),cpe=e,cpe)}function NV(){NV=U,Wge=new Cq("ELK",0),lPe=new Cq("JSON",1),uPe=new Cq("DOT",2),hPe=new Cq("SVG",3)}function yA(){yA=U,Sde=new _se("STACKED",0),Cde=new _se("REVERSE_STACKED",1),MB=new _se("SEQUENCED",2)}function xA(){xA=U,ZDe=new Ose(Id,0),Ide=new Ose("MIDDLE_TO_MIDDLE",1),OB=new Ose("AVOID_OVERLAP",2)}function TE(){TE=U,oLe=new MZ,cLe=new lI,X8t=new yj,Y8t=new DZ,W8t=new n8,aLe=(nr(W8t),new ke)}function PV(){PV=U,WNe=new lw(15),XSt=new Ha((pi(),_2),WNe),MM=n9,VNe=LSt,UNe=kv,KNe=i7,GNe=C4}function Q5(e,t){var n,r,a,o,f;for(r=t,a=0,o=r.length;a=e.b.c.length||(K7e(e,2*t+1),n=2*t+2,n0&&(t.Cd(n),n.i&&C4n(n))}function W7e(e,t,n){var r;for(r=n-1;r>=0&&e[r]===t[r];r--);return r<0?0:fse(va(e[r],Vo),va(t[r],Vo))?-1:1}function A0t(e,t,n){var r,a;this.g=e,this.c=t,this.a=this,this.d=this,a=cft(n),r=We(c6t,TP,227,a,0,1),this.b=r}function Cce(e,t,n,r,a){var o,f;for(f=n;f<=a;f++)for(o=t;o<=r;o++)if(r6(e,o,f))return!0;return!1}function Lyn(e,t){var n,r;for(r=e.Zb().Cc().Kc();r.Ob();)if(n=l(r.Pb(),16),n.Hc(t))return!0;return!1}function L0t(e,t,n){var r,a,o,f;for(nr(n),f=!1,o=e.fd(t),a=n.Kc();a.Ob();)r=a.Pb(),o.Rb(r),f=!0;return f}function Sce(e,t){var n,r;return r=l(Kn(e.a,4),129),n=We(epe,r0e,424,t,0,1),r!=null&&pu(r,0,n,0,r.length),n}function M0t(e,t){var n;return n=new ele((e.f&256)!=0,e.i,e.a,e.d,(e.f&16)!=0,e.j,e.g,t),e.e!=null||(n.c=e),n}function Myn(e,t){var n;return e===t?!0:De(t,85)?(n=l(t,85),Qxe(Mm(e),n.vc())):!1}function D0t(e,t,n){var r,a;for(a=n.Kc();a.Ob();)if(r=l(a.Pb(),44),e.Be(t,r.md()))return!0;return!1}function I0t(e,t,n){return e.d[t.p][n.p]||(O6n(e,t,n),e.d[t.p][n.p]=!0,e.d[n.p][t.p]=!0),e.a[t.p][n.p]}function Dyn(e,t){var n;return!e||e==t||!ns(t,(ft(),u3))?!1:(n=l(Q(t,(ft(),u3)),10),n!=e)}function _ce(e){switch(e.i){case 2:return!0;case 1:return!1;case-1:++e.c;default:return e.$l()}}function O0t(e){switch(e.i){case-2:return!0;case-1:return!1;case 1:--e.c;default:return e._l()}}function N0t(e){xot.call(this,"The given string does not match the expected format for individual spacings.",e)}function Iyn(e,t){var n;t.Ug("Min Size Preprocessing",1),n=a9e(e),Hi(e,(ug(),mM),n.a),Hi(e,UW,n.b),t.Vg()}function Oyn(e){var t,n,r;for(t=0,r=We(Ea,dt,8,e.b,0,1),n=Rr(e,0);n.b!=n.d.c;)r[t++]=l(Br(n),8);return r}function Ace(e,t,n){var r,a,o;for(r=new os,o=Rr(n,0);o.b!=o.d.c;)a=l(Br(o),8),ui(r,new Eo(a));L0t(e,t,r)}function Nyn(e,t){var n;return n=bo(e,t),fse(moe(e,t),0)|Aq(moe(e,n),0)?n:bo(EP,moe(ub(n,63),1))}function Pyn(e,t){var n,r;return n=l(e.d.Bc(t),16),n?(r=e.e.hc(),r.Gc(n),e.e.d-=n.gc(),n.$b(),r):null}function P0t(e){var t;if(t=e.a.c.length,t>0)return qk(t-1,e.a.c.length),t2(e.a,t-1);throw ue(new OQe)}function B0t(e,t,n){if(e>t)throw ue(new Yn(eG+e+Qwt+t));if(e<0||t>n)throw ue(new t3e(eG+e+fEe+t+uEe+n))}function CE(e,t){e.D==null&&e.B!=null&&(e.D=e.B,e.B=null),ece(e,t==null?null:(nr(t),t)),e.C&&e.hl(null)}function Byn(e,t){var n;n=It((Gce(),TW))!=null&&t.Sg()!=null?ze(Ge(t.Sg()))/ze(Ge(It(TW))):1,ki(e.b,t,n)}function Y7e(e,t){var n,r;if(r=e.c[t],r!=0)for(e.c[t]=0,e.d-=r,n=t+1;nMG?e-n>MG:n-e>MG}function K0t(e,t){var n;for(n=0;na&&(Egt(t.q,a),r=n!=t.q.d)),r}function W0t(e,t){var n,r,a,o,f,g,w,E;return w=t.i,E=t.j,r=e.f,a=r.i,o=r.j,f=w-a,g=E-o,n=b.Math.sqrt(f*f+g*g),n}function t8e(e,t){var n,r;return r=XV(e),r||(n=(kle(),P2t(t)),r=new kQe(n),qr(r.El(),e)),r}function DN(e,t){var n,r;return n=l(e.c.Bc(t),16),n?(r=e.hc(),r.Gc(n),e.d-=n.gc(),n.$b(),e.mc(r)):e.jc()}function Kyn(e,t){var n,r;for(r=Jl(e.d,1)!=0,n=!0;n;)n=!1,n=t.c.mg(t.e,r),n=n|cP(e,t,r,!1),r=!r;w7e(e)}function Y0t(e,t,n,r){var a,o;e.a=t,o=r?0:1,e.f=(a=new cpt(e.c,e.a,n,o),new $bt(n,e.a,a,e.e,e.b,e.c==(Iw(),oM)))}function FV(e){var t;return mr(e.a!=e.b),t=e.d.a[e.a],Ert(e.b==e.d.c&&t!=null),e.c=e.a,e.a=e.a+1&e.d.a.length-1,t}function X0t(e){var t;if(e.c!=0)return e.c;for(t=0;t=e.c.b:e.a<=e.c.b))throw ue(new _c);return t=e.a,e.a+=e.c.c,++e.b,pt(t)}function Oce(e){var t;return t=new bye(e.a),pc(t,e),rt(t,(ft(),zi),e),t.o.a=e.g,t.o.b=e.f,t.n.a=e.i,t.n.b=e.j,t}function Nce(e){return(Ct(),hl).Hc(e.j)?ze(Ge(Q(e,(ft(),zT)))):Ic(he(le(Ea,1),dt,8,0,[e.i.n,e.n,e.a])).b}function Yyn(e){var t;return t=Oq(TEt),l(Q(e,(ft(),Lu)),21).Hc((Ho(),$T))&&fi(t,(uo(),bu),(vo(),RK)),t}function Xyn(e){var t,n,r,a;for(a=new Ks,r=new G(e);r.a=0?t:-t;r>0;)r%2==0?(n*=n,r=r/2|0):(a*=n,r-=1);return t<0?1/a:a}function t4n(e,t){var n,r,a;for(a=1,n=e,r=t>=0?t:-t;r>0;)r%2==0?(n*=n,r=r/2|0):(a*=n,r-=1);return t<0?1/a:a}function yb(e,t){var n,r,a,o;return o=(a=e?XV(e):null,Dpt((r=t,a&&a.Gl(),r))),o==t&&(n=XV(e),n&&n.Gl()),o}function Q0t(e,t,n){var r,a;return a=e.f,e.f=t,e.Db&4&&!(e.Db&1)&&(r=new _a(e,1,0,a,t),n?n.nj(r):n=r),n}function J0t(e,t,n){var r,a;return a=e.b,e.b=t,e.Db&4&&!(e.Db&1)&&(r=new _a(e,1,3,a,t),n?n.nj(r):n=r),n}function r8e(e,t,n){var r,a;return a=e.a,e.a=t,e.Db&4&&!(e.Db&1)&&(r=new _a(e,1,1,a,t),n?n.nj(r):n=r),n}function Z0t(e){var t,n;if(e!=null)for(n=0;n=r||t-129&&e<128?(Fit(),t=e+128,n=t_e[t],!n&&(n=t_e[t]=new Cr(e)),n):new Cr(e)}function _E(e){var t,n;return e>-129&&e<128?(est(),t=e+128,n=s_e[t],!n&&(n=s_e[t]=new Wn(e)),n):new Wn(e)}function n1t(e,t){var n;e.a.c.length>0&&(n=l(jt(e.a,e.a.c.length-1),579),G7e(n,t))||vt(e.a,new yut(t))}function o4n(e){u0();var t,n;t=e.d.c-e.e.c,n=l(e.g,154),Vu(n.b,new pYe(t)),Vu(n.c,new bYe(t)),to(n.i,new mYe(t))}function r1t(e){var t;return t=new tb,t.a+="VerticalSegment ",wu(t,e.e),t.a+=" ",hi(t,Eye(new Zie,new G(e.k))),t.a}function Pce(e,t){var n,r,a;for(n=0,a=Oc(e,t).Kc();a.Ob();)r=l(a.Pb(),12),n+=Q(r,(ft(),jl))!=null?1:0;return n}function e6(e,t,n){var r,a,o;for(r=0,o=Rr(e,0);o.b!=o.d.c&&(a=ze(Ge(Br(o))),!(a>n));)a>=t&&++r;return r}function i1t(e,t){Xr(e);try{return e._b(t)}catch(n){if(n=bs(n),De(n,212)||De(n,169))return!1;throw ue(n)}}function s8e(e,t){Xr(e);try{return e.Hc(t)}catch(n){if(n=bs(n),De(n,212)||De(n,169))return!1;throw ue(n)}}function c4n(e,t){Xr(e);try{return e.Mc(t)}catch(n){if(n=bs(n),De(n,212)||De(n,169))return!1;throw ue(n)}}function Oy(e,t){Xr(e);try{return e.xc(t)}catch(n){if(n=bs(n),De(n,212)||De(n,169))return null;throw ue(n)}}function u4n(e,t){Xr(e);try{return e.Bc(t)}catch(n){if(n=bs(n),De(n,212)||De(n,169))return null;throw ue(n)}}function TA(e,t){switch(t.g){case 2:case 1:return Oc(e,t);case 3:case 4:return lf(Oc(e,t))}return Cn(),Cn(),_o}function CA(e){var t;return e.Db&64?g0(e):(t=new Af(g0(e)),t.a+=" (name: ",Xo(t,e.zb),t.a+=")",t.a)}function l4n(e){var t;return t=l(B1(e.c.c,""),233),t||(t=new nx(Ck(Tk(new ny,""),"Other")),h2(e.c.c,"",t)),t}function a8e(e,t,n){var r,a;return a=e.sb,e.sb=t,e.Db&4&&!(e.Db&1)&&(r=new _a(e,1,4,a,t),n?n.nj(r):n=r),n}function o8e(e,t,n){var r,a;return a=e.r,e.r=t,e.Db&4&&!(e.Db&1)&&(r=new _a(e,1,8,a,e.r),n?n.nj(r):n=r),n}function h4n(e,t,n){var r,a;return r=new Zg(e.e,4,13,(a=t.c,a||(Tn(),td)),null,f2(e,t),!1),n?n.nj(r):n=r,n}function f4n(e,t,n){var r,a;return r=new Zg(e.e,3,13,null,(a=t.c,a||(Tn(),td)),f2(e,t),!1),n?n.nj(r):n=r,n}function o2(e,t){var n,r;return n=l(t,691),r=n.el(),!r&&n.fl(r=De(t,90)?new Btt(e,l(t,29)):new sct(e,l(t,156))),r}function IN(e,t,n){var r;e._i(e.i+1),r=e.Zi(t,n),t!=e.i&&pu(e.g,t,e.g,t+1,e.i-t),Ts(e.g,t,r),++e.i,e.Mi(t,n),e.Ni()}function d4n(e,t){var n;return t.a&&(n=t.a.a.length,e.a?hi(e.a,e.b):e.a=new Th(e.d),fct(e.a,t.a,t.d.length,n)),e}function g4n(e,t){var n;e.c=t,e.a=w5n(t),e.a<54&&(e.f=(n=t.d>1?lct(t.a[0],t.a[1]):lct(t.a[0],0),Fm(t.e>0?n:r2(n))))}function ON(e,t){var n;return n=new on,e.a.Bd(n)?(Ok(),new Kie(nr(Ult(e,n.a,t)))):(fb(e),Ok(),Ok(),b_e)}function s1t(e,t){var n;e.c.length!=0&&(n=l(j1(e,We(wg,m2,10,e.c.length,0,1)),199),cye(n,new U9),Jpt(n,t))}function a1t(e,t){var n;e.c.length!=0&&(n=l(j1(e,We(wg,m2,10,e.c.length,0,1)),199),cye(n,new Wd),Jpt(n,t))}function Pi(e,t){return Ia(e)?vn(e,t):fy(e)?eit(e,t):hy(e)?(nr(e),qe(e)===qe(t)):t5e(e)?e.Fb(t):W4e(e)?Jtt(e,t):W5e(e,t)}function cf(e,t,n){if(t<0)d9e(e,n);else{if(!n.rk())throw ue(new Yn(Ob+n.xe()+kL));l(n,69).wk().Ek(e,e.hi(),t)}}function o1t(e,t,n){if(e<0||t>n)throw ue(new tc(eG+e+fEe+t+", size: "+n));if(e>t)throw ue(new Yn(eG+e+Qwt+t))}function c1t(e){var t;return e.Db&64?g0(e):(t=new Af(g0(e)),t.a+=" (source: ",Xo(t,e.d),t.a+=")",t.a)}function u1t(e){return e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:e>=48&&e<=57?e-48:0}function p4n(e){YU();var t,n,r,a;for(n=eue(),r=0,a=n.length;r=0?kb(e):J_(kb(r2(e))))}function f1t(e,t,n,r,a,o){this.e=new bt,this.f=(qo(),sM),vt(this.e,e),this.d=t,this.a=n,this.b=r,this.f=a,this.c=o}function v4n(e,t,n){e.n=Lm(nm,[dt,ahe],[376,28],14,[n,ua(b.Math.ceil(t/32))],2),e.o=t,e.p=n,e.j=t-1>>1,e.k=n-1>>1}function d1t(e){return e-=e>>1&1431655765,e=(e>>2&858993459)+(e&858993459),e=(e>>4)+e&252645135,e+=e>>8,e+=e>>16,e&63}function g1t(e,t){var n,r;for(r=new or(e);r.e!=r.i.gc();)if(n=l(gr(r),142),qe(t)===qe(n))return!0;return!1}function w4n(e,t,n){var r,a,o;return o=(a=VE(e.b,t),a),o&&(r=l(VU(lN(e,o),""),29),r)?P9e(e,r,t,n):null}function Bce(e,t,n){var r,a,o;return o=(a=VE(e.b,t),a),o&&(r=l(VU(lN(e,o),""),29),r)?B9e(e,r,t,n):null}function y4n(e,t){var n;if(n=X5(e.i,t),n==null)throw ue(new dd("Node did not exist in input."));return S7e(t,n),null}function x4n(e,t){var n;if(n=oP(e,t),De(n,331))return l(n,35);throw ue(new Yn(Ob+t+"' is not a valid attribute"))}function _A(e,t,n){var r;if(r=e.gc(),t>r)throw ue(new my(t,r));if(e.Si()&&e.Hc(n))throw ue(new Yn(WP));e.Gi(t,n)}function k4n(e,t){t.Ug("Sort end labels",1),Is(Fi(Dc(new bn(null,new kn(e.b,16)),new hj),new J7),new aZ),t.Vg()}function Js(){Js=U,J1=new mO(cL,0),vc=new mO(Dx,1),uc=new mO(Mx,2),Q1=new mO(whe,3),wf=new mO("UP",4)}function PN(){PN=U,WW=new $se("P1_STRUCTURE",0),YW=new $se("P2_PROCESSING_ORDER",1),XW=new $se("P3_EXECUTION",2)}function p1t(){p1t=U,jTt=Td(Td(v_(Td(Td(v_(fi(new Xs,(wx(),lM),(WA(),Dde)),hM),YDe),QDe),fM),UDe),JDe)}function E4n(e){switch(l(Q(e,(ft(),hv)),311).g){case 1:rt(e,hv,(ep(),Ux));break;case 2:rt(e,hv,(ep(),F6))}}function T4n(e){switch(e){case 0:return new nJe;case 1:return new eJe;case 2:return new tJe;default:throw ue(new YI)}}function b1t(e){switch(e.g){case 2:return vc;case 1:return uc;case 4:return Q1;case 3:return wf;default:return J1}}function h8e(e,t){switch(e.b.g){case 0:case 1:return t;case 2:case 3:return new ef(t.d,0,t.a,t.b);default:return null}}function f8e(e){switch(e.g){case 1:return er;case 2:return Qn;case 3:return ar;case 4:return Dr;default:return Pc}}function BN(e){switch(e.g){case 1:return Dr;case 2:return er;case 3:return Qn;case 4:return ar;default:return Pc}}function $V(e){switch(e.g){case 1:return ar;case 2:return Dr;case 3:return er;case 4:return Qn;default:return Pc}}function d8e(e,t,n,r){switch(t){case 1:return!e.n&&(e.n=new nt(ec,e,1,7)),e.n;case 2:return e.k}return sxe(e,t,n,r)}function AA(e,t,n){var r,a;return e.Pj()?(a=e.Qj(),r=Hue(e,t,n),e.Jj(e.Ij(7,pt(n),r,t,a)),r):Hue(e,t,n)}function Fce(e,t){var n,r,a;e.d==null?(++e.e,--e.f):(a=t.ld(),n=t.Bi(),r=(n&Ii)%e.d.length,uvn(e,r,j2t(e,r,n,a)))}function AE(e,t){var n;n=(e.Bb&m0)!=0,t?e.Bb|=m0:e.Bb&=-1025,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,10,n,t))}function LE(e,t){var n;n=(e.Bb&Xy)!=0,t?e.Bb|=Xy:e.Bb&=-4097,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,12,n,t))}function ME(e,t){var n;n=(e.Bb&Sl)!=0,t?e.Bb|=Sl:e.Bb&=-8193,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,15,n,t))}function DE(e,t){var n;n=(e.Bb&r4)!=0,t?e.Bb|=r4:e.Bb&=-2049,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,11,n,t))}function C4n(e){var t;e.g&&(t=e.c.kg()?e.f:e.a,Y9e(t.a,e.o,!0),Y9e(t.a,e.o,!1),rt(e.o,(Nt(),Ms),(Ra(),Tv)))}function S4n(e){var t;if(!e.a)throw ue(new nc("Cannot offset an unassigned cut."));t=e.c-e.b,e.b+=t,zat(e,t),$at(e,t)}function _4n(e,t){var n;if(n=cr(e.k,t),n==null)throw ue(new dd("Port did not exist in input."));return S7e(t,n),null}function A4n(e){var t,n;for(n=B2t(Ah(e)).Kc();n.Ob();)if(t=ei(n.Pb()),YA(e,t))return Lmn((met(),R_t),t);return null}function m1t(e){var t,n;for(n=e.p.a.ec().Kc();n.Ob();)if(t=l(n.Pb(),218),t.f&&e.b[t.c]<-1e-10)return t;return null}function L4n(e){var t,n;for(n=hb(new tb,91),t=!0;e.Ob();)t||(n.a+=Co),t=!1,wu(n,e.Pb());return(n.a+="]",n).a}function M4n(e){var t,n,r;for(t=new bt,r=new G(e.b);r.at?1:e==t?e==0?Yi(1/e,1/t):0:isNaN(e)?isNaN(t)?0:1:-1}function I4n(e){var t;return t=e.a[e.c-1&e.a.length-1],t==null?null:(e.c=e.c-1&e.a.length-1,Ts(e.a,e.c,null),t)}function O4n(e){var t,n,r;for(r=0,n=e.length,t=0;t=1?vc:Q1):n}function F4n(e){switch(l(Q(e,(Nt(),bp)),223).g){case 1:return new Tee;case 3:return new Lee;default:return new Eee}}function xb(e){if(e.c)xb(e.c);else if(e.d)throw ue(new nc("Stream already terminated, can't be modified or used"))}function Bw(e,t,n){var r;return r=e.a.get(t),e.a.set(t,n===void 0?null:n),r===void 0?(++e.c,++e.b.g):++e.d,r}function R4n(e,t,n){var r,a;for(a=e.a.ec().Kc();a.Ob();)if(r=l(a.Pb(),10),EN(n,l(jt(t,r.p),16)))return r;return null}function p8e(e,t,n){var r;return r=0,t&&(B5(e.a)?r+=t.f.a/2:r+=t.f.b/2),n&&(B5(e.a)?r+=n.f.a/2:r+=n.f.b/2),r}function j4n(e,t,n){var r;r=n,!r&&(r=B4e(new L8,0)),r.Ug(L3t,2),kdt(e.b,t,r.eh(1)),eMn(e,t,r.eh(1)),rIn(t,r.eh(1)),r.Vg()}function b8e(e,t,n){var r,a;return r=(rb(),a=new AS,a),dV(r,t),fV(r,n),e&&qr((!e.a&&(e.a=new Ys(qh,e,5)),e.a),r),r}function jce(e){var t;return e.Db&64?g0(e):(t=new Af(g0(e)),t.a+=" (identifier: ",Xo(t,e.k),t.a+=")",t.a)}function $ce(e,t){var n;n=(e.Bb&eu)!=0,t?e.Bb|=eu:e.Bb&=-32769,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,18,n,t))}function m8e(e,t){var n;n=(e.Bb&eu)!=0,t?e.Bb|=eu:e.Bb&=-32769,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,18,n,t))}function IE(e,t){var n;n=(e.Bb&_d)!=0,t?e.Bb|=_d:e.Bb&=-16385,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,16,n,t))}function v8e(e,t){var n;n=(e.Bb&Io)!=0,t?e.Bb|=Io:e.Bb&=-65537,e.Db&4&&!(e.Db&1)&&Ni(e,new h0(e,1,20,n,t))}function w8e(e){var t;return t=We(kf,Ad,28,2,15,1),e-=Io,t[0]=(e>>10)+AP&Zs,t[1]=(e&1023)+56320&Zs,If(t,0,t.length)}function $4n(e){var t;return t=jy(e),t>34028234663852886e22?gs:t<-34028234663852886e22?ia:t}function bo(e,t){var n;return wc(e)&&wc(t)&&(n=e+t,_P"+Bm(t.c):"e_"+es(t),e.b&&e.c?Bm(e.b)+"->"+Bm(e.c):"e_"+es(e))}function H4n(e,t){return vn(t.b&&t.c?Bm(t.b)+"->"+Bm(t.c):"e_"+es(t),e.b&&e.c?Bm(e.b)+"->"+Bm(e.c):"e_"+es(e))}function Fw(e,t){return A1(),f0(Ab),b.Math.abs(e-t)<=Ab||e==t||isNaN(e)&&isNaN(t)?0:et?1:uw(isNaN(e),isNaN(t))}function ip(){ip=U,Hge=new xq(cL,0),JB=new xq("POLYLINE",1),iC=new xq("ORTHOGONAL",2),s9=new xq("SPLINES",3)}function qV(){qV=U,YIe=new Rse("ASPECT_RATIO_DRIVEN",0),uge=new Rse("MAX_SCALE_DRIVEN",1),WIe=new Rse("AREA_DRIVEN",2)}function V4n(e,t,n){var r;try{dyn(e,t,n)}catch(a){throw a=bs(a),De(a,606)?(r=a,ue(new w6e(r))):ue(a)}return t}function U4n(e){var t,n,r;for(n=0,r=e.length;nt&&r.Ne(e[o-1],e[o])>0;--o)f=e[o],Ts(e,o,e[o-1]),Ts(e,o-1,f)}function sn(e,t){var n,r,a,o,f;if(n=t.f,h2(e.c.d,n,t),t.g!=null)for(a=t.g,o=0,f=a.length;ot){pct(n);break}}zO(n,t)}function Y4n(e,t){var n,r,a;r=G5(t),a=ze(Ge(Py(r,(Nt(),x0)))),n=b.Math.max(0,a/2-.5),FA(t,n,1),vt(e,new Net(t,n))}function X4n(e,t,n){var r;n.Ug("Straight Line Edge Routing",1),n.dh(t,yCe),r=l(at(t,(H5(),Y6)),27),rvt(e,r),n.dh(t,OG)}function y8e(e,t){e.n.c.length==0&&vt(e.n,new PH(e.s,e.t,e.i)),vt(e.b,t),exe(l(jt(e.n,e.n.c.length-1),209),t),jmt(e,t)}function LA(e){var t;this.a=(t=l(e.e&&e.e(),9),new Zh(t,l(c0(t,t.length),9),0)),this.b=We(wa,Rn,1,this.a.a.length,5,1)}function xc(e){var t;return Array.isArray(e)&&e.Tm===xe?_m(bh(e))+"@"+(t=es(e)>>>0,t.toString(16)):e.toString()}function Q4n(e,t){return e.h==SP&&e.m==0&&e.l==0?(t&&(Nb=qu(0,0,0)),ent((iE(),YSe))):(t&&(Nb=qu(e.l,e.m,e.h)),qu(0,0,0))}function J4n(e,t){switch(t.g){case 2:return e.b;case 1:return e.c;case 4:return e.d;case 3:return e.a;default:return!1}}function x1t(e,t){switch(t.g){case 2:return e.b;case 1:return e.c;case 4:return e.d;case 3:return e.a;default:return!1}}function x8e(e,t,n,r){switch(t){case 3:return e.f;case 4:return e.g;case 5:return e.i;case 6:return e.j}return d8e(e,t,n,r)}function HV(e,t){if(t==e.d)return e.e;if(t==e.e)return e.d;throw ue(new Yn("Node "+t+" not part of edge "+e))}function Z4n(e,t){var n;if(n=oP(e.Dh(),t),De(n,102))return l(n,19);throw ue(new Yn(Ob+t+"' is not a valid reference"))}function uf(e,t,n,r){if(t<0)$9e(e,n,r);else{if(!n.rk())throw ue(new Yn(Ob+n.xe()+kL));l(n,69).wk().Ck(e,e.hi(),t,r)}}function Ql(e){var t;if(e.b){if(Ql(e.b),e.b.d!=e.c)throw ue(new Xh)}else e.d.dc()&&(t=l(e.f.c.xc(e.e),16),t&&(e.d=t))}function e5n(e){py();var t,n,r,a;for(t=e.o.b,r=l(l($i(e.r,(Ct(),Dr)),21),87).Kc();r.Ob();)n=l(r.Pb(),117),a=n.e,a.b+=t}function t5n(e){var t,n,r;for(this.a=new bd,r=new G(e);r.a=a)return t.c+n;return t.c+t.b.gc()}function r5n(e,t){Fk();var n,r,a,o;for(r=Olt(e),a=t,nE(r,0,r.length,a),n=0;n0&&(r+=a,++n);return n>1&&(r+=e.d*(n-1)),r}function s5n(e){var t,n,r,a,o;return o=jxe(e),n=ZI(e.c),r=!n,r&&(a=new $p,e1(o,"knownLayouters",a),t=new uQe(a),to(e.c,t)),o}function T8e(e){var t,n,r;for(r=new Up,r.a+="[",t=0,n=e.gc();t0&&(Xn(t-1,e.length),e.charCodeAt(t-1)==58)&&!Hce(e,$M,zM))}function C8e(e,t){var n;return qe(e)===qe(t)?!0:De(t,92)?(n=l(t,92),e.e==n.e&&e.d==n.d&&Imn(e,n.a)):!1}function gx(e){switch(Ct(),e.g){case 4:return Qn;case 1:return ar;case 3:return Dr;case 2:return er;default:return Pc}}function u5n(e){var t,n;if(e.b)return e.b;for(n=G1?null:e.d;n;){if(t=G1?null:n.b,t)return t;n=G1?null:n.d}return Dk(),w_e}function S8e(e){var t,n,r;for(r=ze(Ge(e.a.of((pi(),iY)))),n=new G(e.a.Sf());n.a>5,t=e&31,r=We(Vr,di,28,n+1,15,1),r[n]=1<3;)a*=10,--o;e=(e+(a>>1))/a|0}return r.i=e,!0}function ms(e,t){var n,r,a;if(n=(e.i==null&&Sd(e),e.i),r=t.Lj(),r!=-1){for(a=n.length;r=0;--r)for(t=n[r],a=0;a>1,this.k=t-1>>1}function T5n(e){ZH(),l(e.of((pi(),Ub)),181).Hc((Zl(),hY))&&(l(e.of(S4),181).Fc((Rl(),a9)),l(e.of(Ub),181).Mc(hY))}function A1t(e){var t,n;t=e.d==(yx(),IT),n=Lxe(e),t&&!n||!t&&n?rt(e.a,(Nt(),Rd),(og(),VB)):rt(e.a,(Nt(),Rd),(og(),HB))}function Gce(){Gce=U,tq(),TW=(Nt(),m3),Qkt=O1(he(le(Cge,1),oCe,149,0,[SB,x0,H6,b3,y4,cde,GT,KT,ude,tM,q6,vv,V6]))}function C5n(e,t){var n;return n=l(yc(e,Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15),n.Qc(Yit(n.gc()))}function L1t(e,t){var n,r;if(r=new ba(e.a.ad(t,!0)),r.a.gc()<=1)throw ue(new S8);return n=r.a.ec().Kc(),n.Pb(),l(n.Pb(),40)}function S5n(e,t,n){var r,a;return r=ze(e.p[t.i.p])+ze(e.d[t.i.p])+t.n.b+t.a.b,a=ze(e.p[n.i.p])+ze(e.d[n.i.p])+n.n.b+n.a.b,a-r}function O8e(e,t){var n;return e.i>0&&(t.lengthe.i&&Ts(t,e.i,null),t}function UV(e){var t;return e.Db&64?CA(e):(t=new Af(CA(e)),t.a+=" (instanceClassName: ",Xo(t,e.D),t.a+=")",t.a)}function GV(e){var t,n,r,a;for(a=0,n=0,r=e.length;n0?(e._j(),r=t==null?0:es(t),a=(r&Ii)%e.d.length,n=j2t(e,a,r,t),n!=-1):!1}function M1t(e,t){var n,r;e.a=bo(e.a,1),e.c=b.Math.min(e.c,t),e.b=b.Math.max(e.b,t),e.d+=t,n=t-e.f,r=e.e+n,e.f=r-e.e-n,e.e=r}function N8e(e,t){switch(t){case 3:Mw(e,0);return;case 4:Dw(e,0);return;case 5:Uu(e,0);return;case 6:Gu(e,0);return}i8e(e,t)}function Rw(e,t){switch(t.g){case 1:return G8(e.j,(kl(),xAe));case 2:return G8(e.j,(kl(),EAe));default:return Cn(),Cn(),_o}}function P8e(e){ww();var t;switch(t=e.Pc(),t.length){case 0:return x0e;case 1:return new Sae(Xr(t[0]));default:return new ooe(U4n(t))}}function D1t(e,t){e.Xj();try{e.d.bd(e.e++,t),e.f=e.d.j,e.g=-1}catch(n){throw n=bs(n),De(n,77)?ue(new Xh):ue(n)}}function Wce(){Wce=U,ipe=new NS,MPe=new H0,DPe=new AI,IPe=new LI,OPe=new f8,NPe=new tre,PPe=new nre,BPe=new rre,FPe=new ire}function KV(e,t){iye();var n,r;return n=MO((zz(),zz(),NL)),r=null,t==n&&(r=l(xu(KSe,e),624)),r||(r=new Xst(e),t==n&&rc(KSe,e,r)),r}function I1t(e){By();var t;return(e.q?e.q:(Cn(),Cn(),mg))._b((Nt(),g3))?t=l(Q(e,g3),203):t=l(Q(eo(e),eM),203),t}function Py(e,t){var n,r;return r=null,ns(e,(Nt(),kW))&&(n=l(Q(e,kW),96),n.pf(t)&&(r=n.of(t))),r==null&&(r=Q(eo(e),t)),r}function O1t(e,t){var n,r,a;return De(t,44)?(n=l(t,44),r=n.ld(),a=Oy(e.Rc(),r),yd(a,n.md())&&(a!=null||e.Rc()._b(r))):!1}function n1(e,t){var n,r,a;return e.f>0&&(e._j(),r=t==null?0:es(t),a=(r&Ii)%e.d.length,n=y9e(e,a,r,t),n)?n.md():null}function Ru(e,t,n){var r,a,o;return e.Pj()?(r=e.i,o=e.Qj(),IN(e,r,t),a=e.Ij(3,null,t,r,o),n?n.nj(a):n=a):IN(e,e.i,t),n}function A5n(e,t,n){var r,a;return r=new Zg(e.e,4,10,(a=t.c,De(a,90)?l(a,29):(Tn(),Kf)),null,f2(e,t),!1),n?n.nj(r):n=r,n}function L5n(e,t,n){var r,a;return r=new Zg(e.e,3,10,null,(a=t.c,De(a,90)?l(a,29):(Tn(),Kf)),f2(e,t),!1),n?n.nj(r):n=r,n}function N1t(e){py();var t;return t=new Eo(l(e.e.of((pi(),i7)),8)),e.B.Hc((Zl(),aC))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t}function kb(e){Cd();var t,n;return n=Yr(e),t=Yr(ub(e,32)),t!=0?new qot(n,t):n>10||n<0?new Qg(1,n):y6t[n]}function RN(e,t){var n;return wc(e)&&wc(t)&&(n=e%t,_P=0?o=o.a[1]:(a=o,o=o.a[0])}return a}function $N(e,t,n){var r,a,o;for(a=null,o=e.b;o;){if(r=e.a.Ne(t,o.d),n&&r==0)return o;r<=0?o=o.a[0]:(a=o,o=o.a[1])}return a}function P5n(e,t,n,r){var a,o,f;return a=!1,RMn(e.f,n,r)&&(r6n(e.f,e.a[t][n],e.a[t][r]),o=e.a[t],f=o[r],o[r]=o[n],o[n]=f,a=!0),a}function R1t(e,t,n){var r,a,o,f;for(a=l(cr(e.b,n),183),r=0,f=new G(t.j);f.a>5,t&=31,a=e.d+n+(t==0?0:1),r=We(Vr,di,28,a,15,1),Oxn(r,e.a,n,t),o=new Im(e.e,a,r),iA(o),o}function B5n(e,t){var n,r,a;for(r=new hr(dr(qs(e).a.Kc(),new j));jr(r);)if(n=l(xr(r),18),a=n.d.i,a.c==t)return!1;return!0}function R8e(e,t,n){var r,a,o,f,g;return f=e.k,g=t.k,r=n[f.g][g.g],a=Ge(Py(e,r)),o=Ge(Py(t,r)),b.Math.max((nr(a),a),(nr(o),o))}function F5n(){return Error.stackTraceLimit>0?(b.Error.stackTraceLimit=Error.stackTraceLimit=64,!0):"stack"in new Error}function R5n(e,t){return A1(),A1(),f0(Ab),(b.Math.abs(e-t)<=Ab||e==t||isNaN(e)&&isNaN(t)?0:et?1:uw(isNaN(e),isNaN(t)))>0}function j8e(e,t){return A1(),A1(),f0(Ab),(b.Math.abs(e-t)<=Ab||e==t||isNaN(e)&&isNaN(t)?0:et?1:uw(isNaN(e),isNaN(t)))<0}function $1t(e,t){return A1(),A1(),f0(Ab),(b.Math.abs(e-t)<=Ab||e==t||isNaN(e)&&isNaN(t)?0:et?1:uw(isNaN(e),isNaN(t)))<=0}function Xce(e,t){for(var n=0;!t[n]||t[n]=="";)n++;for(var r=t[n++];n0&&this.b>0&&(this.g=aH(this.c,this.b,this.a))}function j5n(e,t){var n=e.a,r;t=String(t),n.hasOwnProperty(t)&&(r=n[t]);var a=(vce(),_0e)[typeof r],o=a?a(r):Z7e(typeof r);return o}function NE(e){var t,n,r;if(r=null,t=Pd in e.a,n=!t,n)throw ue(new dd("Every element must have an id."));return r=xx(Wg(e,Pd)),r}function jw(e){var t,n;for(n=fpt(e),t=null;e.c==2;)Li(e),t||(t=(Di(),Di(),new B_(2)),Qm(t,n),n=t),n.Jm(fpt(e));return n}function YV(e,t){var n,r,a;return e._j(),r=t==null?0:es(t),a=(r&Ii)%e.d.length,n=y9e(e,a,r,t),n?(Wht(e,n),n.md()):null}function K1t(e,t){return e.e>t.e?1:e.et.d?e.e:e.d=48&&e<48+b.Math.min(10,10)?e-48:e>=97&&e<97?e-97+10:e>=65&&e<65?e-65+10:-1}function $5n(e,t){if(t.c==e)return t.d;if(t.d==e)return t.c;throw ue(new Yn("Input edge is not connected to the input port."))}function z5n(e){if(QV(wT,e))return Hn(),ST;if(QV(Ffe,e))return Hn(),Pb;throw ue(new Yn("Expecting true or false"))}function q8e(e){switch(typeof e){case Ile:return s2(e);case Qke:return j8(e);case Cx:return Art(e);default:return e==null?0:fw(e)}}function Td(e,t){if(e.a<0)throw ue(new nc("Did not call before(...) or after(...) before calling add(...)."));return Bye(e,e.a,t),e}function H8e(e){return BH(),De(e,162)?l(cr(lF,C6t),295).Rg(e):Hu(lF,bh(e))?l(cr(lF,bh(e)),295).Rg(e):null}function Ku(e){var t,n;return e.Db&32||(n=(t=l(Kn(e,16),29),yr(t||e.ii())-yr(e.ii())),n!=0&&px(e,32,We(wa,Rn,1,n,5,1))),e}function px(e,t,n){var r;e.Db&t?n==null?TEn(e,t):(r=mue(e,t),r==-1?e.Eb=n:Ts(jm(e.Eb),r,n)):n!=null&&KCn(e,t,n)}function q5n(e,t,n,r){var a,o;t.c.length!=0&&(a=FTn(n,r),o=Rkn(t),Is(lV(new bn(null,new kn(o,1)),new a8),new Cat(e,n,a,r)))}function H5n(e,t){var n,r,a,o;return r=e.a.length-1,n=t-e.b&r,o=e.c-t&r,a=e.c-e.b&r,Ert(n=o?(zyn(e,t),-1):($yn(e,t),1)}function XV(e){var t,n,r;if(r=e.Jh(),!r)for(t=0,n=e.Ph();n;n=n.Ph()){if(++t>ohe)return n.Qh();if(r=n.Jh(),r||n==e)break}return r}function Y1t(e,t){var n;return qe(t)===qe(e)?!0:!De(t,21)||(n=l(t,21),n.gc()!=e.gc())?!1:e.Ic(n)}function V5n(e,t){return e.et.e?1:e.ft.f?1:es(e)-es(t)}function QV(e,t){return nr(e),t==null?!1:vn(e,t)?!0:e.length==t.length&&vn(e.toLowerCase(),t.toLowerCase())}function ap(e){var t,n;return iu(e,-129)>0&&iu(e,128)<0?(Zit(),t=Yr(e)+128,n=n_e[t],!n&&(n=n_e[t]=new Or(e)),n):new Or(e)}function Km(){Km=U,c4=new dq(Id,0),bAe=new dq("INSIDE_PORT_SIDE_GROUPS",1),o1e=new dq("GROUP_MODEL_ORDER",2),c1e=new dq($Ee,3)}function U5n(e){var t;return e.b||Run(e,(t=Ffn(e.e,e.a),!t||!vn(Ffe,n1((!t.b&&(t.b=new dh((Tn(),No),Yc,t)),t.b),"qualified")))),e.c}function G5n(e,t){var n,r;for(n=(Xn(t,e.length),e.charCodeAt(t)),r=t+1;r2e3&&(l6t=e,oK=b.setTimeout(Hun,10))),aK++==0?(swn((Xwe(),GSe)),!0):!1}function a6n(e,t,n){var r;(I6t?(u5n(e),!0):O6t||P6t?(Dk(),!0):N6t&&(Dk(),!1))&&(r=new fit(t),r.b=n,g9n(e,r))}function Jce(e,t){var n;n=!e.A.Hc((mh(),Cv))||e.q==(Ra(),Mu),e.u.Hc((Rl(),vp))?n?YDn(e,t):Vvt(e,t):e.u.Hc(Yb)&&(n?pDn(e,t):swt(e,t))}function tdt(e){var t;qe(at(e,(pi(),n7)))===qe((rp(),oY))&&(ds(e)?(t=l(at(ds(e),n7),346),Hi(e,n7,t)):Hi(e,n7,DM))}function o6n(e){var t,n;return ns(e.d.i,(Nt(),HT))?(t=l(Q(e.c.i,HT),17),n=l(Q(e.d.i,HT),17),ru(t.a,n.a)>0):!1}function ndt(e,t,n){return new ef(b.Math.min(e.a,t.a)-n/2,b.Math.min(e.b,t.b)-n/2,b.Math.abs(e.a-t.a)+n,b.Math.abs(e.b-t.b)+n)}function rdt(e){var t;this.d=new bt,this.j=new qa,this.g=new qa,t=e.g.b,this.f=l(Q(eo(t),(Nt(),Rh)),88),this.e=ze(Ge(tU(t,y4)))}function idt(e){this.d=new bt,this.e=new e2,this.c=We(Vr,di,28,(Ct(),he(le(Oo,1),au,64,0,[Pc,Qn,ar,Dr,er])).length,15,1),this.b=e}function G8e(e,t,n){var r;switch(r=n[e.g][t],e.g){case 1:case 3:return new lt(0,r);case 2:case 4:return new lt(r,0);default:return null}}function sdt(e,t,n){var r,a;a=l(GO(t.f),205);try{a.rf(e,n),lat(t.f,a)}catch(o){throw o=bs(o),De(o,103)?(r=o,ue(r)):ue(o)}}function adt(e,t,n){var r,a,o,f,g,w;return r=null,g=Fke(hE(),t),o=null,g&&(a=null,w=Pke(g,n),f=null,w!=null&&(f=e.qf(g,w)),a=f,o=a),r=o,r}function Zce(e,t,n,r){var a;if(a=e.length,t>=a)return a;for(t=t>0?t:0;tr&&Ts(t,r,null),t}function odt(e,t){var n,r;for(r=e.a.length,t.lengthr&&Ts(t,r,null),t}function PE(e,t){var n,r;if(++e.j,t!=null&&(n=(r=e.a.Cb,De(r,99)?l(r,99).th():null),fEn(t,n))){px(e.a,4,n);return}px(e.a,4,l(t,129))}function c6n(e){var t;if(e==null)return null;if(t=dTn(Tu(e,!0)),t==null)throw ue(new Jie("Invalid hexBinary value: '"+e+"'"));return t}function JV(e,t,n){var r;t.a.length>0&&(vt(e.b,new Ait(t.a,n)),r=t.a.length,0r&&(t.a+=Mnt(We(kf,Ad,28,-r,15,1))))}function cdt(e,t,n){var r,a,o;if(!n[t.d])for(n[t.d]=!0,a=new G(Z5(t));a.a=e.b>>1)for(r=e.c,n=e.b;n>t;--n)r=r.b;else for(r=e.a.a,n=0;n=0?e.Wh(a):que(e,r)):n<0?que(e,r):l(r,69).wk().Bk(e,e.hi(),n)}function fdt(e){var t,n,r;for(r=(!e.o&&(e.o=new xl((su(),Cg),L2,e,0)),e.o),n=r.c.Kc();n.e!=n.i.gc();)t=l(n.Yj(),44),t.md();return iN(r)}function It(e){var t;if(De(e.a,4)){if(t=H8e(e.a),t==null)throw ue(new nc(Nyt+e.b+"'. "+Oyt+(Gg(hF),hF.k)+JCe));return t}else return e.a}function b6n(e,t){var n,r;if(e.j.length!=t.j.length)return!1;for(n=0,r=e.j.length;n=64&&t<128&&(a=Q0(a,l0(1,t-64)));return a}function tU(e,t){var n,r;return r=null,ns(e,(pi(),r9))&&(n=l(Q(e,r9),96),n.pf(t)&&(r=n.of(t))),r==null&&eo(e)&&(r=Q(eo(e),t)),r}function m6n(e,t){var n;return n=l(Q(e,(Nt(),cc)),75),Zse(t,O8t)?n?Ch(n):(n=new bl,rt(e,cc,n)):n&&rt(e,cc,null),n}function IA(){IA=U,X_e=(pi(),_Ne),W0e=oNe,I7t=Z6,Y_e=_2,B7t=(dU(),A_e),P7t=S_e,F7t=M_e,N7t=C_e,O7t=(Lce(),G_e),K0e=L7t,W_e=M7t,vK=D7t}function nU(e){switch(w3e(),this.c=new bt,this.d=e,e.g){case 0:case 2:this.a=_5e(pAe),this.b=gs;break;case 3:case 1:this.a=pAe,this.b=ia}}function v6n(e){var t;U8(l(Q(e,(Nt(),Ms)),101))&&(t=e.b,e2t((Sn(0,t.c.length),l(t.c[0],30))),e2t(l(jt(t,t.c.length-1),30)))}function w6n(e,t){t.Ug("Self-Loop post-processing",1),Is(Fi(Fi(Dc(new bn(null,new kn(e.b,16)),new RZ),new jZ),new $Z),new Ej),t.Vg()}function ddt(e,t,n){var r,a;if(e.c)Uu(e.c,e.c.i+t),Gu(e.c,e.c.j+n);else for(a=new G(e.b);a.a=0&&(n.d=e.t);break;case 3:e.t>=0&&(n.a=e.t)}e.C&&(n.b=e.C.b,n.c=e.C.c)}function OA(){OA=U,vDe=new hO(cCe,0),vde=new hO($he,1),wde=new hO("LINEAR_SEGMENTS",2),rM=new hO("BRANDES_KOEPF",3),iM=new hO(cyt,4)}function NA(){NA=U,uB=new hq(nG,0),bK=new hq(yhe,1),mK=new hq(xhe,2),lB=new hq(khe,3),uB.a=!1,bK.a=!0,mK.a=!1,lB.a=!0}function bx(){bx=U,aB=new lq(nG,0),sB=new lq(yhe,1),oB=new lq(xhe,2),cB=new lq(khe,3),aB.a=!1,sB.a=!0,oB.a=!1,cB.a=!0}function mx(e,t,n,r){var a;return n>=0?e.Sh(t,n,r):(e.Ph()&&(r=(a=e.Fh(),a>=0?e.Ah(r):e.Ph().Th(e,-1-a,null,r))),e.Ch(t,n,r))}function K8e(e,t){switch(t){case 7:!e.e&&(e.e=new Ln(js,e,7,4)),$r(e.e);return;case 8:!e.d&&(e.d=new Ln(js,e,8,5)),$r(e.d);return}N8e(e,t)}function Hi(e,t,n){return n==null?(!e.o&&(e.o=new xl((su(),Cg),L2,e,0)),YV(e.o,t)):(!e.o&&(e.o=new xl((su(),Cg),L2,e,0)),GN(e.o,t,n)),e}function mdt(e,t){Cn();var n,r,a,o;for(n=e,o=t,De(e,21)&&!De(t,21)&&(n=t,o=e),a=n.Kc();a.Ob();)if(r=a.Pb(),o.Hc(r))return!1;return!0}function T6n(e,t,n,r){if(t.an.b)return!0}return!1}function iue(e,t){return Ia(e)?!!r6t[t]:e.Sm?!!e.Sm[t]:fy(e)?!!n6t[t]:hy(e)?!!t6t[t]:!1}function C6n(e){var t;t=e.a;do t=l(xr(new hr(dr(ka(t).a.Kc(),new j))),18).c.i,t.k==(Zn(),Aa)&&e.b.Fc(t);while(t.k==(Zn(),Aa));e.b=lf(e.b)}function vdt(e,t){var n,r,a;for(a=e,r=new hr(dr(ka(t).a.Kc(),new j));jr(r);)n=l(xr(r),18),n.c.i.c&&(a=b.Math.max(a,n.c.i.c.p));return a}function S6n(e,t){var n,r,a;for(a=0,r=l(l($i(e.r,t),21),87).Kc();r.Ob();)n=l(r.Pb(),117),a+=n.d.d+n.b.Mf().b+n.d.a,r.Ob()&&(a+=e.w);return a}function _6n(e,t){var n,r,a;for(a=0,r=l(l($i(e.r,t),21),87).Kc();r.Ob();)n=l(r.Pb(),117),a+=n.d.b+n.b.Mf().a+n.d.c,r.Ob()&&(a+=e.w);return a}function wdt(e){var t,n,r,a;if(r=0,a=Hy(e),a.c.length==0)return 1;for(n=new G(a);n.a=0?e.Lh(f,n,!0):Hw(e,o,n)):l(o,69).wk().yk(e,e.hi(),a,n,r)}function D6n(e,t,n,r){var a,o;o=t.pf((pi(),r7))?l(t.of(r7),21):e.j,a=p4n(o),a!=(YU(),H0e)&&(n&&!$8e(a)||Jxe(gTn(e,a,r),t))}function I6n(e){switch(e.g){case 1:return Pw(),iB;case 3:return Pw(),rB;case 2:return Pw(),U0e;case 4:return Pw(),V0e;default:return null}}function O6n(e,t,n){if(e.e)switch(e.b){case 1:Epn(e.c,t,n);break;case 0:Tpn(e.c,t,n)}else $ct(e.c,t,n);e.a[t.p][n.p]=e.c.i,e.a[n.p][t.p]=e.c.e}function ydt(e){var t,n;if(e==null)return null;for(n=We(wg,dt,199,e.length,0,2),t=0;t=0)return a;if(e.ol()){for(r=0;r=a)throw ue(new my(t,a));if(e.Si()&&(r=e.dd(n),r>=0&&r!=t))throw ue(new Yn(WP));return e.Xi(t,n)}function W8e(e,t){if(this.a=l(Xr(e),253),this.b=l(Xr(t),253),e.Ed(t)>0||e==(Uie(),w0e)||t==(Gie(),y0e))throw ue(new Yn("Invalid range: "+Hct(e,t)))}function xdt(e){var t,n;for(this.b=new bt,this.c=e,this.a=!1,n=new G(e.a);n.a0),(t&-t)==t)return ua(t*Jl(e,31)*4656612873077393e-25);do n=Jl(e,31),r=n%t;while(n-r+(t-1)<0);return ua(r)}function j6n(e,t,n){switch(n.g){case 1:e.a=t.a/2,e.b=0;break;case 2:e.a=t.a,e.b=t.b/2;break;case 3:e.a=t.a/2,e.b=t.b;break;case 4:e.a=0,e.b=t.b/2}}function zN(e,t,n,r){var a,o;for(a=t;a1&&(o=P6n(e,t)),o}function Tdt(e){var t;return t=ze(Ge(at(e,(pi(),QB))))*b.Math.sqrt((!e.a&&(e.a=new nt(Ai,e,10,11)),e.a).i),new lt(t,t/ze(Ge(at(e,sY))))}function aue(e){var t;return e.f&&e.f.Vh()&&(t=l(e.f,54),e.f=l(yb(e,t),84),e.f!=t&&e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,9,8,t,e.f))),e.f}function oue(e){var t;return e.i&&e.i.Vh()&&(t=l(e.i,54),e.i=l(yb(e,t),84),e.i!=t&&e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,9,7,t,e.i))),e.i}function Ro(e){var t;return e.b&&e.b.Db&64&&(t=e.b,e.b=l(yb(e,t),19),e.b!=t&&e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,9,21,t,e.b))),e.b}function oU(e,t){var n,r,a;e.d==null?(++e.e,++e.f):(r=t.Bi(),cCn(e,e.f+1),a=(r&Ii)%e.d.length,n=e.d[a],!n&&(n=e.d[a]=e.dk()),n.Fc(t),++e.f)}function Q8e(e,t,n){var r;return t.tk()?!1:t.Ik()!=-2?(r=t.ik(),r==null?n==null:Pi(r,n)):t.qk()==e.e.Dh()&&n==null}function cU(){var e;Mh(16,Pwt),e=cft(16),this.b=We(k0e,TP,303,e,0,1),this.c=We(k0e,TP,303,e,0,1),this.a=null,this.e=null,this.i=0,this.f=e-1,this.g=0}function op(e){r4e.call(this),this.k=(Zn(),Ps),this.j=(Mh(6,Yy),new Bu(6)),this.b=(Mh(2,Yy),new Bu(2)),this.d=new $ie,this.f=new Rwe,this.a=e}function z6n(e){var t,n;e.c.length<=1||(t=Abt(e,(Ct(),Dr)),ppt(e,l(t.a,17).a,l(t.b,17).a),n=Abt(e,er),ppt(e,l(n.a,17).a,l(n.b,17).a))}function q6n(e,t,n){var r,a;for(a=e.a.b,r=a.c.length;r102?-1:e<=57?e-48:e<65?-1:e<=70?e-65+10:e<97?-1:e-97+10}function fue(e,t){if(e==null)throw ue(new D8("null key in entry: null="+t));if(t==null)throw ue(new D8("null value in entry: "+e+"=null"))}function U6n(e,t){for(var n,r;e.Ob();)if(!t.Ob()||(n=e.Pb(),r=t.Pb(),!(qe(n)===qe(r)||n!=null&&Pi(n,r))))return!1;return!t.Ob()}function _dt(e,t){var n;return n=he(le(Na,1),Zo,28,15,[Dce(e.a[0],t),Dce(e.a[1],t),Dce(e.a[2],t)]),e.d&&(n[0]=b.Math.max(n[0],n[2]),n[2]=n[0]),n}function Adt(e,t){var n;return n=he(le(Na,1),Zo,28,15,[BV(e.a[0],t),BV(e.a[1],t),BV(e.a[2],t)]),e.d&&(n[0]=b.Math.max(n[0],n[2]),n[2]=n[0]),n}function Z8e(e,t,n){U8(l(Q(t,(Nt(),Ms)),101))||(d6e(e,t,d2(t,n)),d6e(e,t,d2(t,(Ct(),Dr))),d6e(e,t,d2(t,Qn)),Cn(),Vs(t.j,new IYe(e)))}function Ldt(e){var t,n;for(e.c||lMn(e),n=new bl,t=new G(e.a),re(t);t.a0&&(Xn(0,t.length),t.charCodeAt(0)==43)?(Xn(1,t.length+1),t.substr(1)):t))}function s7n(e){var t;return e==null?null:new ob((t=Tu(e,!0),t.length>0&&(Xn(0,t.length),t.charCodeAt(0)==43)?(Xn(1,t.length+1),t.substr(1)):t))}function txe(e,t,n,r,a,o,f,g){var w,E;r&&(w=r.a[0],w&&txe(e,t,n,w,a,o,f,g),xue(e,n,r.d,a,o,f,g)&&t.Fc(r),E=r.a[1],E&&txe(e,t,n,E,a,o,f,g))}function r6(e,t,n){try{return cw(nce(e,t,n),1)}catch(r){throw r=bs(r),De(r,333)?ue(new tc(Ehe+e.o+"*"+e.p+The+t+Co+n+Che)):ue(r)}}function Ndt(e,t,n){try{return cw(nce(e,t,n),0)}catch(r){throw r=bs(r),De(r,333)?ue(new tc(Ehe+e.o+"*"+e.p+The+t+Co+n+Che)):ue(r)}}function Pdt(e,t,n){try{return cw(nce(e,t,n),2)}catch(r){throw r=bs(r),De(r,333)?ue(new tc(Ehe+e.o+"*"+e.p+The+t+Co+n+Che)):ue(r)}}function Bdt(e,t){if(e.g==-1)throw ue(new pl);e.Xj();try{e.d.hd(e.g,t),e.f=e.d.j}catch(n){throw n=bs(n),De(n,77)?ue(new Xh):ue(n)}}function a7n(e){var t,n,r,a,o;for(r=new G(e.b);r.ao&&Ts(t,o,null),t}function o7n(e,t){var n,r;if(r=e.gc(),t==null){for(n=0;n0&&(w+=a),E[C]=f,f+=g*(w+r)}function Rdt(e){var t,n,r;for(r=e.f,e.n=We(Na,Zo,28,r,15,1),e.d=We(Na,Zo,28,r,15,1),t=0;t0?e.c:0),++a;e.b=r,e.d=o}function Hdt(e,t){var n;return n=he(le(Na,1),Zo,28,15,[X8e(e,(t1(),Gc),t),X8e(e,$u,t),X8e(e,Kc,t)]),e.f&&(n[0]=b.Math.max(n[0],n[2]),n[2]=n[0]),n}function p7n(e,t,n){var r;try{FU(e,t+e.j,n+e.k,!1,!0)}catch(a){throw a=bs(a),De(a,77)?(r=a,ue(new tc(r.g+iG+t+Co+n+")."))):ue(a)}}function b7n(e,t,n){var r;try{FU(e,t+e.j,n+e.k,!0,!1)}catch(a){throw a=bs(a),De(a,77)?(r=a,ue(new tc(r.g+iG+t+Co+n+")."))):ue(a)}}function Vdt(e){var t;ns(e,(Nt(),d3))&&(t=l(Q(e,d3),21),t.Hc((qy(),E0))?(t.Mc(E0),t.Fc(T0)):t.Hc(T0)&&(t.Mc(T0),t.Fc(E0)))}function Udt(e){var t;ns(e,(Nt(),d3))&&(t=l(Q(e,d3),21),t.Hc((qy(),S0))?(t.Mc(S0),t.Fc(qf)):t.Hc(qf)&&(t.Mc(qf),t.Fc(S0)))}function vue(e,t,n,r){var a,o,f,g;return e.a==null&&v9n(e,t),f=t.b.j.c.length,o=n.d.p,g=r.d.p,a=g-1,a<0&&(a=f-1),o<=a?e.a[a]-e.a[o]:e.a[f-1]-e.a[o]+e.a[a]}function m7n(e){var t,n;if(!e.b)for(e.b=$H(l(e.f,27).kh().i),n=new or(l(e.f,27).kh());n.e!=n.i.gc();)t=l(gr(n),135),vt(e.b,new Yie(t));return e.b}function v7n(e){var t,n;if(!e.e)for(e.e=$H(Xae(l(e.f,27)).i),n=new or(Xae(l(e.f,27)));n.e!=n.i.gc();)t=l(gr(n),123),vt(e.e,new BXe(t));return e.e}function Gdt(e){var t,n;if(!e.a)for(e.a=$H(AH(l(e.f,27)).i),n=new or(AH(l(e.f,27)));n.e!=n.i.gc();)t=l(gr(n),27),vt(e.a,new rae(e,t));return e.a}function zw(e){var t;if(!e.C&&(e.D!=null||e.B!=null))if(t=sDn(e),t)e.hl(t);else try{e.hl(null)}catch(n){if(n=bs(n),!De(n,63))throw ue(n)}return e.C}function w7n(e){switch(e.q.g){case 5:bgt(e,(Ct(),Qn)),bgt(e,Dr);break;case 4:vvt(e,(Ct(),Qn)),vvt(e,Dr);break;default:xpt(e,(Ct(),Qn)),xpt(e,Dr)}}function y7n(e){switch(e.q.g){case 5:mgt(e,(Ct(),ar)),mgt(e,er);break;case 4:wvt(e,(Ct(),ar)),wvt(e,er);break;default:kpt(e,(Ct(),ar)),kpt(e,er)}}function i6(e,t){var n,r,a;for(a=new qa,r=e.Kc();r.Ob();)n=l(r.Pb(),36),KE(n,a.a,0),a.a+=n.f.a+t,a.b=b.Math.max(a.b,n.f.b);return a.b>0&&(a.b+=t),a}function hU(e,t){var n,r,a;for(a=new qa,r=e.Kc();r.Ob();)n=l(r.Pb(),36),KE(n,0,a.b),a.b+=n.f.b+t,a.a=b.Math.max(a.a,n.f.a);return a.a>0&&(a.a+=t),a}function Kdt(e){var t,n,r;for(r=Ii,n=new G(e.a);n.a>16==6?e.Cb.Th(e,5,u1,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||e.ii()),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function x7n(e){Xk();var t=e.e;if(t&&t.stack){var n=t.stack,r=t+` +`;return n.substring(0,r.length)==r&&(n=n.substring(r.length)),n.split(` +`)}return[]}function k7n(e){var t;return t=(Qht(),p6t),t[e>>>28]|t[e>>24&15]<<4|t[e>>20&15]<<8|t[e>>16&15]<<12|t[e>>12&15]<<16|t[e>>8&15]<<20|t[e>>4&15]<<24|t[e&15]<<28}function Xdt(e){var t,n,r;e.b==e.c&&(r=e.a.length,n=P7e(b.Math.max(8,r))<<1,e.b!=0?(t=c0(e.a,n),fft(e,t,r),e.a=t,e.b=0):ay(e.a,n),e.c=r)}function E7n(e,t){var n;return n=e.b,n.pf((pi(),rh))?n.ag()==(Ct(),er)?-n.Mf().a-ze(Ge(n.of(rh))):t+ze(Ge(n.of(rh))):n.ag()==(Ct(),er)?-n.Mf().a:t}function HN(e){var t;return e.b.c.length!=0&&l(jt(e.b,0),72).a?l(jt(e.b,0),72).a:(t=Qae(e),t??""+(e.c?gc(e.c.a,e,0):-1))}function fU(e){var t;return e.f.c.length!=0&&l(jt(e.f,0),72).a?l(jt(e.f,0),72).a:(t=Qae(e),t??""+(e.i?gc(e.i.j,e,0):-1))}function T7n(e,t){var n,r;if(t<0||t>=e.gc())return null;for(n=t;n0?e.c:0),a=b.Math.max(a,t.d),++r;e.e=o,e.b=a}function S7n(e){var t,n;if(!e.b)for(e.b=$H(l(e.f,123).kh().i),n=new or(l(e.f,123).kh());n.e!=n.i.gc();)t=l(gr(n),135),vt(e.b,new Yie(t));return e.b}function _7n(e,t){var n,r,a;if(t.dc())return Fk(),Fk(),fF;for(n=new Ort(e,t.gc()),a=new or(e);a.e!=a.i.gc();)r=gr(a),t.Hc(r)&&qr(n,r);return n}function sxe(e,t,n,r){return t==0?r?(!e.o&&(e.o=new xl((su(),Cg),L2,e,0)),e.o):(!e.o&&(e.o=new xl((su(),Cg),L2,e,0)),iN(e.o)):rU(e,t,n,r)}function yue(e){var t,n;if(e.rb)for(t=0,n=e.rb.i;t>22),a+=r>>22,a<0)?!1:(e.l=n&eh,e.m=r&eh,e.h=a&hp,!0)}function xue(e,t,n,r,a,o,f){var g,w;return!(t.Te()&&(w=e.a.Ne(n,r),w<0||!a&&w==0)||t.Ue()&&(g=e.a.Ne(n,o),g>0||!f&&g==0))}function D7n(e,t){TE();var n;if(n=e.j.g-t.j.g,n!=0)return 0;switch(e.j.g){case 2:return zce(t,cLe)-zce(e,cLe);case 4:return zce(e,oLe)-zce(t,oLe)}return 0}function I7n(e){switch(e.g){case 0:return D1e;case 1:return I1e;case 2:return O1e;case 3:return N1e;case 4:return QK;case 5:return P1e;default:return null}}function ac(e,t,n){var r,a;return r=(a=new Hie,Gm(a,t),Fu(a,n),qr((!e.c&&(e.c=new nt(k3,e,12,10)),e.c),a),a),i2(r,0),My(r,1),u2(r,!0),c2(r,!0),r}function vx(e,t){var n,r;if(t>=e.i)throw ue(new Vse(t,e.i));return++e.j,n=e.g[t],r=e.i-t-1,r>0&&pu(e.g,t+1,e.g,t,r),Ts(e.g,--e.i,null),e.Qi(t,n),e.Ni(),n}function Qdt(e,t){var n,r;return e.Db>>16==17?e.Cb.Th(e,21,Vf,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||e.ii()),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function O7n(e){var t,n,r,a;for(Cn(),Vs(e.c,e.a),a=new G(e.c);a.an.a.c.length))throw ue(new Yn("index must be >= 0 and <= layer node count"));e.c&&al(e.c.a,e),e.c=n,n&&pw(n.a,t,e)}function ngt(e,t){var n,r,a;for(r=new hr(dr(sp(e).a.Kc(),new j));jr(r);)return n=l(xr(r),18),a=l(t.Kb(n),10),new JS(Xr(a.n.b+a.o.b/2));return o_(),o_(),v0e}function rgt(e,t){this.c=new Pr,this.a=e,this.b=t,this.d=l(Q(e,(ft(),$6)),312),qe(Q(e,(Nt(),GMe)))===qe((cN(),JK))?this.e=new XQe:this.e=new YQe}function BA(e,t){var n,r;return r=null,e.pf((pi(),r9))&&(n=l(e.of(r9),96),n.pf(t)&&(r=n.of(t))),r==null&&e.Tf()&&(r=e.Tf().of(t)),r==null&&(r=It(t)),r}function kue(e,t){var n,r;n=e.fd(t);try{return r=n.Pb(),n.Qb(),r}catch(a){throw a=bs(a),De(a,112)?ue(new tc("Can't remove element "+t)):ue(a)}}function z7n(e,t){var n,r,a;if(r=new Qz,a=new R7e(r.q.getFullYear()-Lb,r.q.getMonth(),r.q.getDate()),n=JAn(e,t,a),n==0||n0?t:0),++n;return new lt(r,a)}function lxe(e,t){var n,r;return e.Db>>16==6?e.Cb.Th(e,6,js,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(su(),pY)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function hxe(e,t){var n,r;return e.Db>>16==7?e.Cb.Th(e,1,oF,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(su(),dPe)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function fxe(e,t){var n,r;return e.Db>>16==9?e.Cb.Th(e,9,Ai,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(su(),pPe)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function agt(e,t){var n,r;return e.Db>>16==5?e.Cb.Th(e,9,TY,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(Tn(),D2)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function ogt(e,t){var n,r;return e.Db>>16==7?e.Cb.Th(e,6,u1,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(Tn(),O2)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function dxe(e,t){var n,r;return e.Db>>16==3?e.Cb.Th(e,0,uF,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(Tn(),M2)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function cgt(){this.a=new T$,this.g=new cU,this.j=new cU,this.b=new Pr,this.d=new cU,this.i=new cU,this.k=new Pr,this.c=new Pr,this.e=new Pr,this.f=new Pr}function V7n(e,t,n){var r,a,o;for(n<0&&(n=0),o=e.i,a=n;aohe)return FE(e,r);if(r==e)return!0}}return!1}function G7n(e){switch(zq(),e.q.g){case 5:Vpt(e,(Ct(),Qn)),Vpt(e,Dr);break;case 4:U2t(e,(Ct(),Qn)),U2t(e,Dr);break;default:Wvt(e,(Ct(),Qn)),Wvt(e,Dr)}}function K7n(e){switch(zq(),e.q.g){case 5:u2t(e,(Ct(),ar)),u2t(e,er);break;case 4:gdt(e,(Ct(),ar)),gdt(e,er);break;default:Yvt(e,(Ct(),ar)),Yvt(e,er)}}function W7n(e){var t,n;t=l(Q(e,(b0(),e8t)),17),t?(n=t.a,n==0?rt(e,(bb(),EK),new Uce):rt(e,(bb(),EK),new VH(n))):rt(e,(bb(),EK),new VH(1))}function Y7n(e,t){var n;switch(n=e.i,t.g){case 1:return-(e.n.b+e.o.b);case 2:return e.n.a-n.o.a;case 3:return e.n.b-n.o.b;case 4:return-(e.n.a+e.o.a)}return 0}function X7n(e,t){switch(e.g){case 0:return t==(hf(),$b)?HK:VK;case 1:return t==(hf(),$b)?HK:pB;case 2:return t==(hf(),$b)?pB:VK;default:return pB}}function UN(e,t){var n,r,a;for(al(e.a,t),e.e-=t.r+(e.a.c.length==0?0:e.c),a=xCe,r=new G(e.a);r.a>16==3?e.Cb.Th(e,12,Ai,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(su(),fPe)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function pxe(e,t){var n,r;return e.Db>>16==11?e.Cb.Th(e,10,Ai,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(su(),gPe)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function ugt(e,t){var n,r;return e.Db>>16==10?e.Cb.Th(e,11,Vf,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(Tn(),I2)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function lgt(e,t){var n,r;return e.Db>>16==10?e.Cb.Th(e,12,Uf,t):(r=Ro(l(Mn((n=l(Kn(e,16),29),n||(Tn(),N4)),e.Db>>16),19)),e.Cb.Th(e,r.n,r.f,t))}function Of(e){var t;return!(e.Bb&1)&&e.r&&e.r.Vh()&&(t=l(e.r,54),e.r=l(yb(e,t),142),e.r!=t&&e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,9,8,t,e.r))),e.r}function Eue(e,t,n){var r;return r=he(le(Na,1),Zo,28,15,[zxe(e,(t1(),Gc),t,n),zxe(e,$u,t,n),zxe(e,Kc,t,n)]),e.f&&(r[0]=b.Math.max(r[0],r[2]),r[2]=r[0]),r}function Q7n(e,t){var n,r,a;if(a=x6n(e,t),a.c.length!=0)for(Vs(a,new pS),n=a.c.length,r=0;r>19,E=t.h>>19,w!=E?E-w:(a=e.h,g=t.h,a!=g?a-g:(r=e.m,f=t.m,r!=f?r-f:(n=e.l,o=t.l,n-o)))}function dU(){dU=U,D_e=(PU(),z0e),M_e=new pn(pEe,D_e),L_e=(aV(),$0e),A_e=new pn(bEe,L_e),__e=(ZV(),j0e),S_e=new pn(mEe,__e),C_e=new pn(vEe,(Hn(),!0))}function FA(e,t,n){var r,a;r=t*n,De(e.g,154)?(a=ix(e),a.f.d?a.f.a||(e.d.a+=r+H1):(e.d.d-=r+H1,e.d.a+=r+H1)):De(e.g,10)&&(e.d.d-=r,e.d.a+=2*r)}function hgt(e,t,n){var r,a,o,f,g;for(a=e[n.g],g=new G(t.d);g.a0?e.b:0),++n;t.b=r,t.e=a}function fgt(e){var t,n,r;if(r=e.b,tet(e.i,r.length)){for(n=r.length*2,e.b=We(k0e,TP,303,n,0,1),e.c=We(k0e,TP,303,n,0,1),e.f=n-1,e.i=0,t=e.a;t;t=t.c)eP(e,t,t);++e.g}}function i8n(e,t,n,r){var a,o,f,g;for(a=0;af&&(g=f/r),a>o&&(w=o/a),md(e,b.Math.min(g,w)),e}function a8n(){zU();var e,t;try{if(t=l(Sxe((ib(),Gf),xT),2113),t)return t}catch(n){if(n=bs(n),De(n,103))e=n,p5e((Jr(),e));else throw ue(n)}return new ik}function o8n(){zU();var e,t;try{if(t=l(Sxe((ib(),Gf),Ff),2040),t)return t}catch(n){if(n=bs(n),De(n,103))e=n,p5e((Jr(),e));else throw ue(n)}return new d8}function c8n(){klt();var e,t;try{if(t=l(Sxe((ib(),Gf),cv),2122),t)return t}catch(n){if(n=bs(n),De(n,103))e=n,p5e((Jr(),e));else throw ue(n)}return new uk}function u8n(e,t,n){var r,a;return a=e.e,e.e=t,e.Db&4&&!(e.Db&1)&&(r=new _a(e,1,4,a,t),n?n.nj(r):n=r),a!=t&&(t?n=ZE(e,SU(e,t),n):n=ZE(e,e.a,n)),n}function dgt(){Qz.call(this),this.e=-1,this.a=!1,this.p=lo,this.k=-1,this.c=-1,this.b=-1,this.g=!1,this.f=-1,this.j=-1,this.n=-1,this.i=-1,this.d=-1,this.o=lo}function l8n(e,t){var n,r,a;if(r=e.b.d.d,e.a||(r+=e.b.d.a),a=t.b.d.d,t.a||(a+=t.b.d.a),n=Yi(r,a),n==0){if(!e.a&&t.a)return-1;if(!t.a&&e.a)return 1}return n}function h8n(e,t){var n,r,a;if(r=e.b.b.d,e.a||(r+=e.b.b.a),a=t.b.b.d,t.a||(a+=t.b.b.a),n=Yi(r,a),n==0){if(!e.a&&t.a)return-1;if(!t.a&&e.a)return 1}return n}function f8n(e,t){var n,r,a;if(r=e.b.g.d,e.a||(r+=e.b.g.a),a=t.b.g.d,t.a||(a+=t.b.g.a),n=Yi(r,a),n==0){if(!e.a&&t.a)return-1;if(!t.a&&e.a)return 1}return n}function mxe(){mxe=U,v8t=yl(fi(fi(fi(new Xs,(uo(),_u),(vo(),KAe)),_u,WAe),mc,YAe),mc,BAe),y8t=fi(fi(new Xs,_u,LAe),_u,FAe),w8t=yl(new Xs,mc,jAe)}function d8n(e){var t,n,r,a,o;for(t=l(Q(e,(ft(),KL)),85),o=e.n,r=t.Cc().Kc();r.Ob();)n=l(r.Pb(),314),a=n.i,a.c+=o.a,a.d+=o.b,n.c?Ibt(n):Obt(n);rt(e,KL,null)}function g8n(e,t,n){var r,a;switch(a=e.b,r=a.d,t.g){case 1:return-r.d-n;case 2:return a.o.a+r.c+n;case 3:return a.o.b+r.a+n;case 4:return-r.b-n;default:return-1}}function p8n(e,t,n){var r,a;for(n.Ug("Interactive node placement",1),e.a=l(Q(t,(ft(),$6)),312),a=new G(t.b);a.a0&&(f=(o&Ii)%e.d.length,a=y9e(e,f,o,t),a)?(g=a.nd(n),g):(r=e.ck(o,t,n),e.c.Fc(r),null)}function yxe(e,t){var n,r,a,o;switch(o2(e,t).Kl()){case 3:case 2:{for(n=d6(t),a=0,o=n.i;a=0;r--)if(vn(e[r].d,t)||vn(e[r].d,n)){e.length>=r+1&&e.splice(0,r+1);break}return e}function KN(e,t){var n;return wc(e)&&wc(t)&&(n=e/t,_P0&&(e.b+=2,e.a+=r):(e.b+=1,e.a+=b.Math.min(r,a))}function ygt(e){var t;t=l(Q(l(ff(e.b,0),40),(Hc(),gIe)),107),rt(e,(Qi(),QT),new lt(0,0)),hmt(new nN,e,t.b+t.c-ze(Ge(Q(e,Bde))),t.d+t.a-ze(Ge(Q(e,Fde))))}function xgt(e,t){var n,r;if(r=!1,Ia(t)&&(r=!0,J8(e,new yy(ei(t)))),r||De(t,242)&&(r=!0,J8(e,(n=g4e(l(t,242)),new vk(n)))),!r)throw ue(new Qie(mSe))}function I8n(e,t,n,r){var a,o,f;return a=new Zg(e.e,1,10,(f=t.c,De(f,90)?l(f,29):(Tn(),Kf)),(o=n.c,De(o,90)?l(o,29):(Tn(),Kf)),f2(e,t),!1),r?r.nj(a):r=a,r}function Exe(e){var t,n;switch(l(Q(eo(e),(Nt(),jMe)),429).g){case 0:return t=e.n,n=e.o,new lt(t.a+n.a/2,t.b+n.b/2);case 1:return new Eo(e.n);default:return null}}function WN(){WN=U,ZK=new C_(Id,0),TLe=new C_("LEFTUP",1),SLe=new C_("RIGHTUP",2),ELe=new C_("LEFTDOWN",3),CLe=new C_("RIGHTDOWN",4),B1e=new C_("BALANCED",5)}function O8n(e,t,n){var r,a,o;if(r=Yi(e.a[t.p],e.a[n.p]),r==0){if(a=l(Q(t,(ft(),Wx)),15),o=l(Q(n,Wx),15),a.Hc(n))return-1;if(o.Hc(t))return 1}return r}function N8n(e){switch(e.g){case 1:return new vne;case 2:return new wne;case 3:return new mne;case 0:return null;default:throw ue(new Yn(Efe+(e.f!=null?e.f:""+e.g)))}}function Txe(e,t,n){switch(t){case 1:!e.n&&(e.n=new nt(ec,e,1,7)),$r(e.n),!e.n&&(e.n=new nt(ec,e,1,7)),As(e.n,l(n,16));return;case 2:fE(e,ei(n));return}V7e(e,t,n)}function Cxe(e,t,n){switch(t){case 3:Mw(e,ze(Ge(n)));return;case 4:Dw(e,ze(Ge(n)));return;case 5:Uu(e,ze(Ge(n)));return;case 6:Gu(e,ze(Ge(n)));return}Txe(e,t,n)}function gU(e,t,n){var r,a,o;o=(r=new Hie,r),a=$1(o,t,null),a&&a.oj(),Fu(o,n),qr((!e.c&&(e.c=new nt(k3,e,12,10)),e.c),o),i2(o,0),My(o,1),u2(o,!0),c2(o,!0)}function Sxe(e,t){var n,r,a;return n=y_(e.i,t),De(n,241)?(a=l(n,241),a.zi()==null,a.wi()):De(n,507)?(r=l(n,2037),a=r.b,a):null}function P8n(e,t,n,r){var a,o;return Xr(t),Xr(n),o=l(H_(e.d,t),17),Wlt(!!o,"Row %s not in %s",t,e.e),a=l(H_(e.b,n),17),Wlt(!!a,"Column %s not in %s",n,e.c),s0t(e,o.a,a.a,r)}function kgt(e,t,n,r,a,o,f){var g,w,E,C,L;if(C=a[o],E=o==f-1,g=E?r:0,L=zdt(g,C),r!=10&&he(le(e,f-o),t[o],n[o],g,L),!E)for(++o,w=0;w1||g==-1?(o=l(w,15),a.Wb(v5n(e,o))):a.Wb(cle(e,l(w,58)))))}function q8n(e,t,n,r){MZe();var a=m0e;function o(){for(var f=0;f0)return!1;return!0}function U8n(e){var t,n,r,a,o;for(r=new qm(new Sr(e.b).a);r.b;)n=Nw(r),t=l(n.ld(),10),o=l(l(n.md(),42).a,10),a=l(l(n.md(),42).b,8),Oi(Y0(t.n),Oi(Ja(o.n),a))}function G8n(e){switch(l(Q(e.b,(Nt(),IMe)),387).g){case 1:Is(fc(Dc(new bn(null,new kn(e.d,16)),new dI),new g5),new wee);break;case 2:zSn(e);break;case 0:wkn(e)}}function K8n(e,t,n){var r,a,o;for(r=n,!r&&(r=new L8),r.Ug("Layout",e.a.c.length),o=new G(e.a);o.awfe)return n;a>-1e-6&&++n}return n}function Axe(e,t){var n;t!=e.b?(n=null,e.b&&(n=IH(e.b,e,-4,n)),t&&(n=mx(t,e,-4,n)),n=J0t(e,t,n),n&&n.oj()):e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,3,t,t))}function Cgt(e,t){var n;t!=e.f?(n=null,e.f&&(n=IH(e.f,e,-1,n)),t&&(n=mx(t,e,-1,n)),n=Q0t(e,t,n),n&&n.oj()):e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,0,t,t))}function Q8n(e,t,n,r){var a,o,f,g;return hh(e.e)&&(a=t.Lk(),g=t.md(),o=n.md(),f=db(e,1,a,g,o,a.Jk()?XE(e,a,o,De(a,102)&&(l(a,19).Bb&Io)!=0):-1,!0),r?r.nj(f):r=f),r}function Sgt(e){var t,n,r;if(e==null)return null;if(n=l(e,15),n.dc())return"";for(r=new Up,t=n.Kc();t.Ob();)Xo(r,(Gi(),ei(t.Pb()))),r.a+=" ";return Gse(r,r.a.length-1)}function _gt(e){var t,n,r;if(e==null)return null;if(n=l(e,15),n.dc())return"";for(r=new Up,t=n.Kc();t.Ob();)Xo(r,(Gi(),ei(t.Pb()))),r.a+=" ";return Gse(r,r.a.length-1)}function J8n(e,t,n){var r,a;return r=e.c[t.c.p][t.p],a=e.c[n.c.p][n.p],r.a!=null&&a.a!=null?Nae(r.a,a.a):r.a!=null?-1:a.a!=null?1:0}function Z8n(e,t,n){return n.Ug("Tree layout",1),qO(e.b),X0(e.b,(wx(),NW),NW),X0(e.b,lM,lM),X0(e.b,hM,hM),X0(e.b,fM,fM),e.a=bP(e.b,t),K8n(e,t,n.eh(1)),n.Vg(),t}function exn(e,t){var n,r,a,o,f,g;if(t)for(o=t.a.length,n=new Dm(o),g=(n.b-n.a)*n.c<0?(sb(),tm):new cb(n);g.Ob();)f=l(g.Pb(),17),a=Jk(t,f.a),r=new GXe(e),cpn(r.a,a)}function txn(e,t){var n,r,a,o,f,g;if(t)for(o=t.a.length,n=new Dm(o),g=(n.b-n.a)*n.c<0?(sb(),tm):new cb(n);g.Ob();)f=l(g.Pb(),17),a=Jk(t,f.a),r=new FXe(e),opn(r.a,a)}function nxn(e){var t;if(e!=null&&e.length>0&&co(e,e.length-1)==33)try{return t=P2t(tf(e,0,e.length-1)),t.e==null}catch(n){if(n=bs(n),!De(n,33))throw ue(n)}return!1}function rxn(e,t,n){var r,a,o;switch(r=eo(t),a=zV(r),o=new gu,Mc(o,t),n.g){case 1:la(o,BN(gx(a)));break;case 2:la(o,gx(a))}return rt(o,(Nt(),m4),Ge(Q(e,m4))),o}function Lxe(e){var t,n;return t=l(xr(new hr(dr(ka(e.a).a.Kc(),new j))),18),n=l(xr(new hr(dr(qs(e.a).a.Kc(),new j))),18),Rt(Bt(Q(t,(ft(),W1))))||Rt(Bt(Q(n,W1)))}function Ry(){Ry=U,bB=new cO("ONE_SIDE",0),KK=new cO("TWO_SIDES_CORNER",1),WK=new cO("TWO_SIDES_OPPOSING",2),GK=new cO("THREE_SIDES",3),UK=new cO("FOUR_SIDES",4)}function Agt(e,t){var n,r,a,o;for(o=new bt,a=0,r=t.Kc();r.Ob();){for(n=pt(l(r.Pb(),17).a+a);n.a=e.f)break;$n(o.c,n)}return o}function ixn(e,t){var n,r,a,o,f;for(o=new G(t.a);o.a0&&Jdt(this,this.c-1,(Ct(),ar)),this.c0&&e[0].length>0&&(this.c=Rt(Bt(Q(eo(e[0][0]),(ft(),zLe))))),this.a=We(kEt,dt,2117,e.length,0,2),this.b=We(EEt,dt,2118,e.length,0,2),this.d=new G0t}function uxn(e){return e.c.length==0?!1:(Sn(0,e.c.length),l(e.c[0],18)).c.i.k==(Zn(),Aa)?!0:W5(fc(new bn(null,new kn(e,16)),new Wee),new Yee)}function Dgt(e,t){var n,r,a,o,f,g,w;for(g=Hy(t),o=t.f,w=t.g,f=b.Math.sqrt(o*o+w*w),a=0,r=new G(g);r.a=0?(n=KN(e,JU),r=RN(e,JU)):(t=ub(e,1),n=KN(t,5e8),r=RN(t,5e8),r=bo(l0(r,1),va(e,1))),Q0(l0(r,32),va(n,Vo))}function Ngt(e,t,n){var r,a;switch(r=(mr(t.b!=0),l(af(t,t.a.a),8)),n.g){case 0:r.b=0;break;case 2:r.b=e.f;break;case 3:r.a=0;break;default:r.a=e.g}return a=Rr(t,0),zO(a,r),t}function Pgt(e,t,n,r){var a,o,f,g,w;switch(w=e.b,o=t.d,f=o.j,g=G8e(f,w.d[f.g],n),a=Oi(Ja(o.n),o.a),o.j.g){case 1:case 3:g.a+=a.a;break;case 2:case 4:g.b+=a.b}Cs(r,g,r.c.b,r.c)}function xxn(e,t,n){var r,a,o,f;for(f=gc(e.e,t,0),o=new Pwe,o.b=n,r=new Ua(e.e,f);r.b1;t>>=1)t&1&&(r=K5(r,n)),n.d==1?n=K5(n,n):n=new Q1t(mmt(n.a,n.d,We(Vr,di,28,n.d<<1,15,1)));return r=K5(r,n),r}function Rxe(){Rxe=U;var e,t,n,r;for(m_e=We(Na,Zo,28,25,15,1),v_e=We(Na,Zo,28,33,15,1),r=152587890625e-16,t=32;t>=0;t--)v_e[t]=r,r*=.5;for(n=1,e=24;e>=0;e--)m_e[e]=n,n*=.5}function _xn(e){var t,n;if(Rt(Bt(at(e,(Nt(),b4))))){for(n=new hr(dr(cp(e).a.Kc(),new j));jr(n);)if(t=l(xr(n),74),qw(t)&&Rt(Bt(at(t,gv))))return!0}return!1}function Bgt(e,t){var n,r,a;na(e.f,t)&&(t.b=e,r=t.c,gc(e.j,r,0)!=-1||vt(e.j,r),a=t.d,gc(e.j,a,0)!=-1||vt(e.j,a),n=t.a.b,n.c.length!=0&&(!e.i&&(e.i=new rdt(e)),I3n(e.i,n)))}function Axn(e){var t,n,r,a,o;return n=e.c.d,r=n.j,a=e.d.d,o=a.j,r==o?n.p=0&&vn(e.substr(t,3),"GMT")||t>=0&&vn(e.substr(t,3),"UTC"))&&(n[0]=t+3),mke(e,n,r)}function Mxn(e,t){var n,r,a,o,f;for(o=e.g.a,f=e.g.b,r=new G(e.d);r.an;o--)e[o]|=t[o-n-1]>>>f,e[o-1]=t[o-n-1]<0&&pu(e.g,t,e.g,t+r,g),f=n.Kc(),e.i+=r,a=0;a>4&15,o=e[r]&15,f[a++]=bPe[n],f[a++]=bPe[o];return If(f,0,f.length)}function cl(e){var t,n;return e>=Io?(t=AP+(e-Io>>10&1023)&Zs,n=56320+(e-Io&1023)&Zs,String.fromCharCode(t)+(""+String.fromCharCode(n))):String.fromCharCode(e&Zs)}function zxn(e,t){py();var n,r,a,o;return a=l(l($i(e.r,t),21),87),a.gc()>=2?(r=l(a.Kc().Pb(),117),n=e.u.Hc((Rl(),PM)),o=e.u.Hc(a9),!r.a&&!n&&(a.gc()==2||o)):!1}function jgt(e,t,n,r,a){var o,f,g;for(o=Tbt(e,t,n,r,a),g=!1;!o;)TU(e,a,!0),g=!0,o=Tbt(e,t,n,r,a);g&&TU(e,a,!1),f=bce(a),f.c.length!=0&&(e.d&&e.d.Gg(f),jgt(e,a,n,r,f))}function vU(){vU=U,Uge=new L_(Id,0),$Ne=new L_("DIRECTED",1),qNe=new L_("UNDIRECTED",2),RNe=new L_("ASSOCIATION",3),zNe=new L_("GENERALIZATION",4),jNe=new L_("DEPENDENCY",5)}function qxn(e,t){var n;if(!M1(e))throw ue(new nc(t4t));switch(n=M1(e),t.g){case 1:return-(e.j+e.f);case 2:return e.i-n.g;case 3:return e.j-n.f;case 4:return-(e.i+e.g)}return 0}function Hxn(e,t,n){var r,a,o;return r=t.Lk(),o=t.md(),a=r.Jk()?db(e,4,r,o,null,XE(e,r,o,De(r,102)&&(l(r,19).Bb&Io)!=0),!0):db(e,r.tk()?2:1,r,o,r.ik(),-1,!0),n?n.nj(a):n=a,n}function $E(e,t){var n,r;for(nr(t),r=e.b.c.length,vt(e.b,t);r>0;){if(n=r,r=(r-1)/2|0,e.a.Ne(jt(e.b,r),t)<=0)return rf(e.b,n,t),!0;rf(e.b,n,jt(e.b,r))}return rf(e.b,r,t),!0}function zxe(e,t,n,r){var a,o;if(a=0,n)a=BV(e.a[n.g][t.g],r);else for(o=0;o=g)}function $gt(e){switch(e.g){case 0:return new Sne;case 1:return new _ne;default:throw ue(new Yn("No implementation is available for the width approximator "+(e.f!=null?e.f:""+e.g)))}}function qxe(e,t,n,r){var a;if(a=!1,Ia(r)&&(a=!0,zk(t,n,ei(r))),a||hy(r)&&(a=!0,qxe(e,t,n,r)),a||De(r,242)&&(a=!0,Nm(t,n,l(r,242))),!a)throw ue(new Qie(mSe))}function Uxn(e,t){var n,r,a;if(n=t.qi(e.a),n&&(a=n1((!n.b&&(n.b=new dh((Tn(),No),Yc,n)),n.b),Bf),a!=null)){for(r=1;r<(El(),$Pe).length;++r)if(vn($Pe[r],a))return r}return 0}function Gxn(e,t){var n,r,a;if(n=t.qi(e.a),n&&(a=n1((!n.b&&(n.b=new dh((Tn(),No),Yc,n)),n.b),Bf),a!=null)){for(r=1;r<(El(),zPe).length;++r)if(vn(zPe[r],a))return r}return 0}function zgt(e,t){var n,r,a,o;if(nr(t),o=e.a.gc(),o0?1:0;o.a[a]!=n;)o=o.a[a],a=e.a.Ne(n.d,o.d)>0?1:0;o.a[a]=r,r.b=n.b,r.a[0]=n.a[0],r.a[1]=n.a[1],n.a[0]=null,n.a[1]=null}function Yxn(e){var t,n,r,a;for(t=new bt,n=We(ih,pg,28,e.a.c.length,16,1),l5e(n,n.length),a=new G(e.a);a.a0&&dmt((Sn(0,n.c.length),l(n.c[0],30)),e),n.c.length>1&&dmt(l(jt(n,n.c.length-1),30),e),t.Vg()}function Qxn(e){Rl();var t,n;return t=rs(vp,he(le(cY,1),it,279,0,[Yb])),!(yN(NH(t,e))>1||(n=rs(PM,he(le(cY,1),it,279,0,[NM,a9])),yN(NH(n,e))>1))}function Vxe(e,t){var n;n=xu((ib(),Gf),e),De(n,507)?rc(Gf,e,new Ott(this,t)):rc(Gf,e,this),Nue(this,t),t==(Sk(),APe)?(this.wb=l(this,2038),l(t,2040)):this.wb=(lb(),Vn)}function Jxn(e){var t,n,r;if(e==null)return null;for(t=null,n=0;n=b2?"error":r>=900?"warn":r>=800?"info":"log"),eat(n,e.a),e.b&&G9e(t,n,e.b,"Exception: ",!0))}function Q(e,t){var n,r;return r=(!e.q&&(e.q=new Pr),cr(e.q,t)),r??(n=t.Sg(),De(n,4)&&(n==null?(!e.q&&(e.q=new Pr),ax(e.q,t)):(!e.q&&(e.q=new Pr),ki(e.q,t,n))),n)}function uo(){uo=U,y0=new oO("P1_CYCLE_BREAKING",0),vg=new oO("P2_LAYERING",1),bu=new oO("P3_NODE_ORDERING",2),_u=new oO("P4_NODE_PLACEMENT",3),mc=new oO("P5_EDGE_ROUTING",4)}function Zxn(e,t){hA();var n;if(e.c==t.c){if(e.b==t.b||a3n(e.b,t.b)){if(n=Dln(e.b)?1:-1,e.a&&!t.a)return n;if(!e.a&&t.a)return-n}return ru(e.b.g,t.b.g)}else return Yi(e.c,t.c)}function Ggt(e,t){var n,r,a;if(Gxe(e,t))return!0;for(r=new G(t);r.a=a||t<0)throw ue(new tc(Qfe+t+av+a));if(n>=a||n<0)throw ue(new tc(Jfe+n+av+a));return t!=n?r=(o=e.Cj(n),e.qj(t,o),o):r=e.xj(n),r}function Ygt(e){var t,n,r;if(r=e,e)for(t=0,n=e.Eh();n;n=n.Eh()){if(++t>ohe)return Ygt(n);if(r=n,n==e)throw ue(new nc("There is a cycle in the containment hierarchy of "+e))}return r}function Tb(e){var t,n,r;for(r=new Hm(Co,"[","]"),n=e.Kc();n.Ob();)t=n.Pb(),Jg(r,qe(t)===qe(e)?"(this Collection)":t==null?ul:xc(t));return r.a?r.e.length==0?r.a.a:r.a.a+(""+r.e):r.c}function Gxe(e,t){var n,r;if(r=!1,t.gc()<2)return!1;for(n=0;n1&&(e.j.b+=e.e)):(e.j.a+=n.a,e.j.b=b.Math.max(e.j.b,n.b),e.d.c.length>1&&(e.j.a+=e.e))}function Cb(){Cb=U,axt=he(le(Oo,1),au,64,0,[(Ct(),Qn),ar,Dr]),sxt=he(le(Oo,1),au,64,0,[ar,Dr,er]),oxt=he(le(Oo,1),au,64,0,[Dr,er,Qn]),cxt=he(le(Oo,1),au,64,0,[er,Qn,ar])}function t9n(e,t,n,r){var a,o,f,g,w,E,C;if(f=e.c.d,g=e.d.d,f.j!=g.j)for(C=e.b,a=f.j,w=null;a!=g.j;)w=t==0?$V(a):f8e(a),o=G8e(a,C.d[a.g],n),E=G8e(w,C.d[w.g],n),ui(r,Oi(o,E)),a=w}function n9n(e,t,n,r){var a,o,f,g,w;return f=Zdt(e.a,t,n),g=l(f.a,17).a,o=l(f.b,17).a,r&&(w=l(Q(t,(ft(),jl)),10),a=l(Q(n,jl),10),w&&a&&($ct(e.b,w,a),g+=e.b.i,o+=e.b.e)),g>o}function Qgt(e){var t,n,r,a,o,f,g,w,E;for(this.a=ydt(e),this.b=new bt,n=e,r=0,a=n.length;ruae(e.d).c?(e.i+=e.g.c,Yce(e.d)):uae(e.d).c>uae(e.g).c?(e.e+=e.d.c,Yce(e.g)):(e.i+=cst(e.g),e.e+=cst(e.d),Yce(e.g),Yce(e.d))}function a9n(e,t,n){var r,a,o,f;for(o=t.q,f=t.r,new Pm((J0(),qb),t,o,1),new Pm(qb,o,f,1),a=new G(n);a.ag&&(w=g/r),a>o&&(E=o/a),f=b.Math.min(w,E),e.a+=f*(t.a-e.a),e.b+=f*(t.b-e.b)}function l9n(e,t,n,r,a){var o,f;for(f=!1,o=l(jt(n.b,0),27);jAn(e,t,o,r,a)&&(f=!0,$8n(n,o),n.b.c.length!=0);)o=l(jt(n.b,0),27);return n.b.c.length==0&&UN(n.j,n),f&&lU(t.q),f}function h9n(e,t){h6();var n,r,a,o;if(t.b<2)return!1;for(o=Rr(t,0),n=l(Br(o),8),r=n;o.b!=o.d.c;){if(a=l(Br(o),8),Xue(e,r,a))return!0;r=a}return!!Xue(e,r,n)}function Wxe(e,t,n,r){var a,o;return n==0?(!e.o&&(e.o=new xl((su(),Cg),L2,e,0)),Uq(e.o,t,r)):(o=l(Mn((a=l(Kn(e,16),29),a||e.ii()),n),69),o.wk().Ak(e,Ku(e),n-yr(e.ii()),t,r))}function Nue(e,t){var n;t!=e.sb?(n=null,e.sb&&(n=l(e.sb,54).Th(e,1,RM,n)),t&&(n=l(t,54).Rh(e,1,RM,n)),n=a8e(e,t,n),n&&n.oj()):e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,4,t,t))}function f9n(e,t){var n,r,a,o;if(t)a=np(t,"x"),n=new HXe(e),aE(n.a,(nr(a),a)),o=np(t,"y"),r=new VXe(e),cE(r.a,(nr(o),o));else throw ue(new dd("All edge sections need an end point."))}function d9n(e,t){var n,r,a,o;if(t)a=np(t,"x"),n=new $Xe(e),oE(n.a,(nr(a),a)),o=np(t,"y"),r=new zXe(e),uE(r.a,(nr(o),o));else throw ue(new dd("All edge sections need a start point."))}function g9n(e,t){var n,r,a,o,f,g,w;for(r=_0t(e),o=0,g=r.length;o>22-t,a=e.h<>22-t):t<44?(n=0,r=e.l<>44-t):(n=0,r=0,a=e.l<e)throw ue(new Yn("k must be smaller than n"));return t==0||t==e?1:e==0?0:xxe(e)/(xxe(t)*xxe(e-t))}function Yxe(e,t){var n,r,a,o;for(n=new hye(e);n.g==null&&!n.c?H5e(n):n.g==null||n.i!=0&&l(n.g[n.i-1],51).Ob();)if(o=l(CU(n),58),De(o,167))for(r=l(o,167),a=0;a>4],t[n*2+1]=LY[o&15];return If(t,0,t.length)}function M9n(e){kH();var t,n,r;switch(r=e.c.length,r){case 0:return i6t;case 1:return t=l(Rpt(new G(e)),44),Edn(t.ld(),t.md());default:return n=l(j1(e,We(uv,XU,44,e.c.length,0,1)),173),new Wwe(n)}}function D9n(e){var t,n,r,a,o,f;for(t=new z5,n=new z5,gb(t,e),gb(n,e);n.b!=n.c;)for(a=l(X8(n),36),f=new G(a.a);f.a0&&lP(e,n,t),a):wEn(e,t,n)}function Sb(){Sb=U,uCt=(pi(),n9),lCt=Ev,sCt=kv,aCt=i7,oCt=Ub,iCt=r7,NIe=YB,cCt=S4,Jde=(uke(),KTt),Zde=WTt,BIe=JTt,ege=tCt,FIe=ZTt,RIe=eCt,PIe=YTt,qW=XTt,HW=QTt,FB=nCt,jIe=rCt,OIe=GTt}function spt(e,t){var n,r,a,o,f;if(e.e<=t||tbn(e,e.g,t))return e.g;for(o=e.r,r=e.g,f=e.r,a=(o-r)/2+r;r+11&&(e.e.b+=e.a)):(e.e.a+=n.a,e.e.b=b.Math.max(e.e.b,n.b),e.d.c.length>1&&(e.e.a+=e.a))}function B9n(e){var t,n,r,a;switch(a=e.i,t=a.b,r=a.j,n=a.g,a.a.g){case 0:n.a=(e.g.b.o.a-r.a)/2;break;case 1:n.a=t.d.n.a+t.d.a.a;break;case 2:n.a=t.d.n.a+t.d.a.a-r.a;break;case 3:n.b=t.d.n.b+t.d.a.b}}function F9n(e,t,n){var r,a,o;for(a=new hr(dr(sp(n).a.Kc(),new j));jr(a);)r=l(xr(a),18),!Do(r)&&!(!Do(r)&&r.c.i.c==r.d.i.c)&&(o=Y2t(e,r,n,new QQe),o.c.length>1&&$n(t.c,o))}function opt(e,t,n,r,a){if(rr&&(e.a=r),e.ba&&(e.b=a),e}function R9n(e){if(De(e,143))return pCn(l(e,143));if(De(e,233))return s5n(l(e,233));if(De(e,23))return b9n(l(e,23));throw ue(new Yn(vSe+Tb(new Il(he(le(wa,1),Rn,1,5,[e])))))}function j9n(e,t,n,r,a){var o,f,g;for(o=!0,f=0;f>>a|n[f+r+1]<>>a,++f}return o}function Zxe(e,t,n,r){var a,o,f;if(t.k==(Zn(),Aa)){for(o=new hr(dr(ka(t).a.Kc(),new j));jr(o);)if(a=l(xr(o),18),f=a.c.i.k,f==Aa&&e.c.a[a.c.i.c.p]==r&&e.c.a[t.c.p]==n)return!0}return!1}function $9n(e,t){var n,r,a,o;return t&=63,n=e.h&hp,t<22?(o=n>>>t,a=e.m>>t|n<<22-t,r=e.l>>t|e.m<<22-t):t<44?(o=0,a=n>>>t-22,r=e.m>>t-22|e.h<<44-t):(o=0,a=0,r=n>>>t-44),qu(r&eh,a&eh,o&hp)}function cpt(e,t,n,r){var a;this.b=r,this.e=e==(Iw(),oM),a=t[n],this.d=Lm(ih,[dt,pg],[183,28],16,[a.length,a.length],2),this.a=Lm(Vr,[dt,di],[53,28],15,[a.length,a.length],2),this.c=new Nxe(t,n)}function z9n(e){var t,n,r;for(e.k=new G5e((Ct(),he(le(Oo,1),au,64,0,[Pc,Qn,ar,Dr,er])).length,e.j.c.length),r=new G(e.j);r.a=n)return qE(e,t,r.p),!0;return!1}function o6(e,t,n,r){var a,o,f,g,w,E;for(f=n.length,o=0,a=-1,E=tht((Xn(t,e.length+1),e.substr(t)),(gae(),p_e)),g=0;go&&ggn(E,tht(n[g],p_e))&&(a=g,o=w);return a>=0&&(r[0]=t+o),a}function lpt(e){var t;return e.Db&64?Pue(e):(t=new Th(oSe),!e.a||hi(hi((t.a+=' "',t),e.a),'"'),hi(rw(hi(rw(hi(rw(hi(rw((t.a+=" (",t),e.i),","),e.j)," | "),e.g),","),e.f),")"),t.a)}function hpt(e,t,n){var r,a,o,f,g;for(g=Wu(e.e.Dh(),t),a=l(e.g,124),r=0,f=0;fn?u9e(e,n,"start index"):t<0||t>n?u9e(t,n,"end index"):KA("end index (%s) must not be less than start index (%s)",he(le(wa,1),Rn,1,5,[pt(t),pt(e)]))}function dpt(e,t){var n,r,a,o;for(r=0,a=e.length;r0&&gpt(e,o,n));t.p=0}function Xt(e){var t;this.c=new os,this.f=e.e,this.e=e.d,this.i=e.g,this.d=e.c,this.b=e.b,this.k=e.j,this.a=e.a,e.i?this.j=e.i:this.j=(t=l(K0(xg),9),new Zh(t,l(c0(t,t.length),9),0)),this.g=e.f}function K9n(e){var t,n,r,a;for(t=hb(hi(new Th("Predicates."),"and"),40),n=!0,a=new kr(e);a.b0?g[f-1]:We(wg,m2,10,0,0,1),a=g[f],E=f=0?e.ki(a):d9e(e,r);else throw ue(new Yn(Ob+r.xe()+kL));else throw ue(new Yn(f4t+t+d4t));else cf(e,n,r)}function e9e(e){var t,n;if(n=null,t=!1,De(e,211)&&(t=!0,n=l(e,211).a),t||De(e,263)&&(t=!0,n=""+l(e,263).a),t||De(e,493)&&(t=!0,n=""+l(e,493).a),!t)throw ue(new Qie(mSe));return n}function t9e(e,t,n){var r,a,o,f,g,w;for(w=Wu(e.e.Dh(),t),r=0,g=e.i,a=l(e.g,124),f=0;f=e.d.b.c.length&&(t=new yu(e.d),t.p=r.p-1,vt(e.d.b,t),n=new yu(e.d),n.p=r.p,vt(e.d.b,n)),Va(r,l(jt(e.d.b,r.p),30))}function i9e(e,t,n){var r,a,o;if(!e.b[t.g]){for(e.b[t.g]=!0,r=n,!r&&(r=new nN),ui(r.b,t),o=e.a[t.g].Kc();o.Ob();)a=l(o.Pb(),65),a.b!=t&&i9e(e,a.b,r),a.c!=t&&i9e(e,a.c,r),ui(r.a,a);return r}return null}function Q9n(e){switch(e.g){case 0:case 1:case 2:return Ct(),Qn;case 3:case 4:case 5:return Ct(),Dr;case 6:case 7:case 8:return Ct(),er;case 9:case 10:case 11:return Ct(),ar;default:return Ct(),Pc}}function J9n(e,t){var n;return e.c.length==0?!1:(n=I1t((Sn(0,e.c.length),l(e.c[0],18)).c.i),Sh(),n==(By(),G6)||n==U6?!0:W5(fc(new bn(null,new kn(e,16)),new Xee),new XYe(t)))}function jue(e,t){if(De(t,207))return Gln(e,l(t,27));if(De(t,193))return Kln(e,l(t,123));if(De(t,452))return Uln(e,l(t,166));throw ue(new Yn(vSe+Tb(new Il(he(le(wa,1),Rn,1,5,[t])))))}function ypt(e,t,n){var r,a;if(this.f=e,r=l(cr(e.b,t),260),a=r?r.a:0,k6e(n,a),n>=(a/2|0))for(this.e=r?r.c:null,this.d=a;n++0;)G6e(this);this.b=t,this.a=null}function Z9n(e,t){var n,r;t.a?OCn(e,t):(n=l(cse(e.b,t.b),60),n&&n==e.a[t.b.f]&&n.a&&n.a!=t.b.a&&n.c.Fc(t.b),r=l(ose(e.b,t.b),60),r&&e.a[r.f]==t.b&&r.a&&r.a!=t.b.a&&t.b.c.Fc(r),tae(e.b,t.b))}function xpt(e,t){var n,r;if(n=l(Qo(e.b,t),127),l(l($i(e.r,t),21),87).dc()){n.n.b=0,n.n.c=0;return}n.n.b=e.C.b,n.n.c=e.C.c,e.A.Hc((mh(),Cv))&&Kbt(e,t),r=_6n(e,t),Jue(e,t)==(t6(),Kb)&&(r+=2*e.w),n.a.a=r}function kpt(e,t){var n,r;if(n=l(Qo(e.b,t),127),l(l($i(e.r,t),21),87).dc()){n.n.d=0,n.n.a=0;return}n.n.d=e.C.d,n.n.a=e.C.a,e.A.Hc((mh(),Cv))&&Wbt(e,t),r=S6n(e,t),Jue(e,t)==(t6(),Kb)&&(r+=2*e.w),n.a.b=r}function ekn(e,t){var n,r,a,o;for(o=new bt,r=new G(t);r.ar&&(Xn(t-1,e.length),e.charCodeAt(t-1)<=32);)--t;return r>0||tn.a&&(r.Hc((Ym(),EM))?a=(t.a-n.a)/2:r.Hc(TM)&&(a=t.a-n.a)),t.b>n.b&&(r.Hc((Ym(),SM))?o=(t.b-n.b)/2:r.Hc(CM)&&(o=t.b-n.b)),Hxe(e,a,o)}function Lpt(e,t,n,r,a,o,f,g,w,E,C,L,B){De(e.Cb,90)&&zy(Yl(l(e.Cb,90)),4),Fu(e,n),e.f=f,LE(e,g),DE(e,w),AE(e,E),ME(e,C),u2(e,L),IE(e,B),c2(e,!0),i2(e,a),e.Zk(o),Gm(e,t),r!=null&&(e.i=null,xV(e,r))}function u9e(e,t,n){if(e<0)return KA(Swt,he(le(wa,1),Rn,1,5,[n,pt(e)]));if(t<0)throw ue(new Yn(_wt+t));return KA("%s (%s) must not be greater than size (%s)",he(le(wa,1),Rn,1,5,[n,pt(e),pt(t)]))}function l9e(e,t,n,r,a,o){var f,g,w,E;if(f=r-n,f<7){W4n(t,n,r,o);return}if(w=n+a,g=r+a,E=w+(g-w>>1),l9e(t,e,w,E,-a,o),l9e(t,e,E,g,-a,o),o.Ne(e[E-1],e[E])<=0){for(;n=0?e.bi(o,n):$9e(e,a,n);else throw ue(new Yn(Ob+a.xe()+kL));else throw ue(new Yn(f4t+t+d4t));else uf(e,r,a,n)}function Mpt(e){var t,n;if(e.f){for(;e.n>0;){if(t=l(e.k.Xb(e.n-1),76),n=t.Lk(),De(n,102)&&l(n,19).Bb&eu&&(!e.e||n.pk()!=oC||n.Lj()!=0)&&t.md()!=null)return!0;--e.n}return!1}else return e.n>0}function Dpt(e){var t,n,r,a;if(n=l(e,54)._h(),n)try{if(r=null,t=VE((ib(),Gf),bmt(a5n(n))),t&&(a=t.ai(),a&&(r=a.Fl(oun(n.e)))),r&&r!=e)return Dpt(r)}catch(o){if(o=bs(o),!De(o,63))throw ue(o)}return e}function bkn(e,t,n){var r,a,o;n.Ug("Remove overlaps",1),n.dh(t,yCe),r=l(at(t,(H5(),Y6)),27),e.f=r,e.a=sue(l(at(t,(Sb(),FB)),300)),a=Ge(at(t,(pi(),Ev))),_e(e,(nr(a),a)),o=Hy(r),Rvt(e,t,o,n),n.dh(t,OG)}function mkn(e){var t,n,r;if(Rt(Bt(at(e,(pi(),KB))))){for(r=new bt,n=new hr(dr(cp(e).a.Kc(),new j));jr(n);)t=l(xr(n),74),qw(t)&&Rt(Bt(at(t,Oge)))&&$n(r.c,t);return r}else return Cn(),Cn(),_o}function Ipt(e){if(!e)return MJe(),d6t;var t=e.valueOf?e.valueOf():e;if(t!==e){var n=_0e[typeof t];return n?n(t):Z7e(typeof t)}else return e instanceof Array||e instanceof b.Array?new Sz(e):new wk(e)}function Opt(e,t,n){var r,a,o;switch(o=e.o,r=l(Qo(e.p,n),252),a=r.i,a.b=nP(r),a.a=tP(r),a.b=b.Math.max(a.b,o.a),a.b>o.a&&!t&&(a.b=o.a),a.c=-(a.b-o.a)/2,n.g){case 1:a.d=-a.a;break;case 3:a.d=o.b}hle(r),fle(r)}function Npt(e,t,n){var r,a,o;switch(o=e.o,r=l(Qo(e.p,n),252),a=r.i,a.b=nP(r),a.a=tP(r),a.a=b.Math.max(a.a,o.b),a.a>o.b&&!t&&(a.a=o.b),a.d=-(a.a-o.b)/2,n.g){case 4:a.c=-a.b;break;case 2:a.c=o.a}hle(r),fle(r)}function vkn(e,t){var n,r,a,o,f;if(!t.dc()){if(a=l(t.Xb(0),131),t.gc()==1){hbt(e,a,a,1,0,t);return}for(n=1;n0)try{a=Oh(t,lo,Ii)}catch(o){throw o=bs(o),De(o,130)?(r=o,ue(new nV(r))):ue(o)}return n=(!e.a&&(e.a=new Pie(e)),e.a),a=0?l(Oe(n,a),58):null}function kkn(e,t){if(e<0)return KA(Swt,he(le(wa,1),Rn,1,5,["index",pt(e)]));if(t<0)throw ue(new Yn(_wt+t));return KA("%s (%s) must be less than size (%s)",he(le(wa,1),Rn,1,5,["index",pt(e),pt(t)]))}function Ekn(e){var t,n,r,a,o;if(e==null)return ul;for(o=new Hm(Co,"[","]"),n=e,r=0,a=n.length;r=0?e.Lh(n,!0,!0):Hw(e,a,!0),160)),l(r,220).Zl(t);else throw ue(new Yn(Ob+t.xe()+kL))}function g9e(e){var t,n;return e>-0x800000000000&&e<0x800000000000?e==0?0:(t=e<0,t&&(e=-e),n=ua(b.Math.floor(b.Math.log(e)/.6931471805599453)),(!t||e!=b.Math.pow(2,n))&&++n,n):Qft(Zc(e))}function Rkn(e){var t,n,r,a,o,f,g;for(o=new bd,n=new G(e);n.a2&&g.e.b+g.j.b<=2&&(a=g,r=f),o.a.zc(a,o),a.q=r);return o}function jkn(e,t,n){n.Ug("Eades radial",1),n.dh(t,OG),e.d=l(at(t,(H5(),Y6)),27),e.c=ze(Ge(at(t,(Sb(),HW)))),e.e=sue(l(at(t,FB),300)),e.a=g5n(l(at(t,jIe),434)),e.b=N8n(l(at(t,PIe),354)),b8n(e),n.dh(t,OG)}function $kn(e,t){if(t.Ug("Target Width Setter",1),P1(e,(z1(),fge)))Hi(e,(ug(),T4),Ge(at(e,fge)));else throw ue(new Vp("A target width has to be set if the TargetWidthWidthApproximator should be used."));t.Vg()}function jpt(e,t){var n,r,a;return r=new op(e),pc(r,t),rt(r,(ft(),aW),t),rt(r,(Nt(),Ms),(Ra(),Mu)),rt(r,Rd,(og(),tY)),x(r,(Zn(),Us)),n=new gu,Mc(n,r),la(n,(Ct(),er)),a=new gu,Mc(a,r),la(a,ar),r}function $pt(e){switch(e.g){case 0:return new Wie((Iw(),DB));case 1:return new Qre;case 2:return new Jre;default:throw ue(new Yn("No implementation is available for the crossing minimizer "+(e.f!=null?e.f:""+e.g)))}}function zpt(e,t){var n,r,a,o,f;for(e.c[t.p]=!0,vt(e.a,t),f=new G(t.j);f.a=o)f.$b();else for(a=f.Kc(),r=0;r0?Zwe():f<0&&Upt(e,t,-f),!0):!1}function tP(e){var t,n,r,a,o,f,g;if(g=0,e.b==0){for(f=_dt(e,!0),t=0,r=f,a=0,o=r.length;a0&&(g+=n,++t);t>1&&(g+=e.c*(t-1))}else g=qJe(cce(xy(Fi(c5e(e.a),new ja),new Ou)));return g>0?g+e.n.d+e.n.a:0}function nP(e){var t,n,r,a,o,f,g;if(g=0,e.b==0)g=qJe(cce(xy(Fi(c5e(e.a),new Xc),new Bc)));else{for(f=Adt(e,!0),t=0,r=f,a=0,o=r.length;a0&&(g+=n,++t);t>1&&(g+=e.c*(t-1))}return g>0?g+e.n.b+e.n.c:0}function Kkn(e){var t,n;if(e.c.length!=2)throw ue(new nc("Order only allowed for two paths."));t=(Sn(0,e.c.length),l(e.c[0],18)),n=(Sn(1,e.c.length),l(e.c[1],18)),t.d.i!=n.c.i&&(e.c.length=0,$n(e.c,n),$n(e.c,t))}function Gpt(e,t,n){var r;for(F5(n,t.g,t.f),Qh(n,t.i,t.j),r=0;r<(!t.a&&(t.a=new nt(Ai,t,10,11)),t.a).i;r++)Gpt(e,l(Oe((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a),r),27),l(Oe((!n.a&&(n.a=new nt(Ai,n,10,11)),n.a),r),27))}function Wkn(e,t){var n,r,a,o;for(o=l(Qo(e.b,t),127),n=o.a,a=l(l($i(e.r,t),21),87).Kc();a.Ob();)r=l(a.Pb(),117),r.c&&(n.a=b.Math.max(n.a,j4e(r.c)));if(n.a>0)switch(t.g){case 2:o.n.c=e.s;break;case 4:o.n.b=e.s}}function Ykn(e,t){var n,r,a;return n=l(Q(t,(b0(),qx)),17).a-l(Q(e,qx),17).a,n==0?(r=ma(Ja(l(Q(e,(bb(),hB)),8)),l(Q(e,$L),8)),a=ma(Ja(l(Q(t,hB),8)),l(Q(t,$L),8)),Yi(r.a*r.b,a.a*a.b)):n}function Xkn(e,t){var n,r,a;return n=l(Q(t,(Hc(),RW)),17).a-l(Q(e,RW),17).a,n==0?(r=ma(Ja(l(Q(e,(Qi(),NB)),8)),l(Q(e,QT),8)),a=ma(Ja(l(Q(t,NB),8)),l(Q(t,QT),8)),Yi(r.a*r.b,a.a*a.b)):n}function Kpt(e){var t,n;return n=new tb,n.a+="e_",t=H3n(e),t!=null&&(n.a+=""+t),e.c&&e.d&&(hi((n.a+=" ",n),fU(e.c)),hi(wu((n.a+="[",n),e.c.i),"]"),hi((n.a+=Phe,n),fU(e.d)),hi(wu((n.a+="[",n),e.d.i),"]")),n.a}function Wpt(e){switch(e.g){case 0:return new aie;case 1:return new dk;case 2:return new sie;case 3:return new iie;default:throw ue(new Yn("No implementation is available for the layout phase "+(e.f!=null?e.f:""+e.g)))}}function m9e(e,t,n,r,a){var o;switch(o=0,a.g){case 1:o=b.Math.max(0,t.b+e.b-(n.b+r));break;case 3:o=b.Math.max(0,-e.b-r);break;case 2:o=b.Math.max(0,-e.a-r);break;case 4:o=b.Math.max(0,t.a+e.a-(n.a+r))}return o}function Qkn(e,t,n){var r,a,o,f,g;if(n)for(a=n.a.length,r=new Dm(a),g=(r.b-r.a)*r.c<0?(sb(),tm):new cb(r);g.Ob();)f=l(g.Pb(),17),o=Jk(n,f.a),hSe in o.a||Yfe in o.a?h_n(e,o,t):MIn(e,o,t),Lhn(l(cr(e.b,NE(o)),74))}function v9e(e){var t,n;switch(e.b){case-1:return!0;case 0:return n=e.t,n>1||n==-1?(e.b=-1,!0):(t=Of(e),t&&(Fo(),t.lk()==g5t)?(e.b=-1,!0):(e.b=1,!1));default:case 1:return!1}}function w9e(e,t){var n,r,a,o;if(Li(e),e.c!=0||e.a!=123)throw ue(new ri(ai((Jr(),B4t))));if(o=t==112,r=e.d,n=Nk(e.i,125,r),n<0)throw ue(new ri(ai((Jr(),F4t))));return a=tf(e.i,r,n),e.d=n+1,vlt(a,o,(e.e&512)==512)}function Ypt(e){var t,n,r,a,o,f,g;if(r=e.a.c.length,r>0)for(f=e.c.d,g=e.d.d,a=md(ma(new lt(g.a,g.b),f),1/(r+1)),o=new lt(f.a,f.b),n=new G(e.a);n.a=0&&r=0?e.Lh(n,!0,!0):Hw(e,a,!0),160)),l(r,220).Wl(t);throw ue(new Yn(Ob+t.xe()+$fe))}function tEn(){x3e();var e;return J_t?l(VE((ib(),Gf),Ff),2038):(wi(uv,new OI),XMn(),e=l(De(xu((ib(),Gf),Ff),560)?xu(Gf,Ff):new fat,560),J_t=!0,QIn(e),iOn(e),ki((y3e(),_Pe),e,new k1),rc(Gf,Ff,e),e)}function nEn(e,t){var n,r,a,o;e.j=-1,hh(e.e)?(n=e.i,o=e.i!=0,tN(e,t),r=new Zg(e.e,3,e.c,null,t,n,o),a=t.zl(e.e,e.c,null),a=Lgt(e,t,a),a?(a.nj(r),a.oj()):Ni(e.e,r)):(tN(e,t),a=t.zl(e.e,e.c,null),a&&a.oj())}function kU(e,t){var n,r,a;if(a=0,r=t[0],r>=e.length)return-1;for(n=(Xn(r,e.length),e.charCodeAt(r));n>=48&&n<=57&&(a=a*10+(n-48),++r,!(r>=e.length));)n=(Xn(r,e.length),e.charCodeAt(r));return r>t[0]?t[0]=r:a=-1,a}function rEn(e){var t,n,r,a,o;return a=l(e.a,17).a,o=l(e.b,17).a,n=a,r=o,t=b.Math.max(b.Math.abs(a),b.Math.abs(o)),a<=0&&a==o?(n=0,r=o-1):a==-t&&o!=t?(n=o,r=a,o>=0&&++n):(n=-o,r=a),new ca(pt(n),pt(r))}function iEn(e,t,n,r){var a,o,f,g,w,E;for(a=0;a=0&&E>=0&&w=e.i)throw ue(new tc(Qfe+t+av+e.i));if(n>=e.i)throw ue(new tc(Jfe+n+av+e.i));return r=e.g[n],t!=n&&(t>16),t=r>>16&16,n=16-t,e=e>>t,r=e-256,t=r>>16&8,n+=t,e<<=t,r=e-Xy,t=r>>16&4,n+=t,e<<=t,r=e-_d,t=r>>16&2,n+=t,e<<=t,r=e>>14,t=r&~(r>>1),n+2-t)}function aEn(e){tx();var t,n,r,a;for(wK=new bt,X0e=new Pr,Y0e=new bt,t=(!e.a&&(e.a=new nt(Ai,e,10,11)),e.a),XDn(t),a=new or(t);a.e!=a.i.gc();)r=l(gr(a),27),gc(wK,r,0)==-1&&(n=new bt,vt(Y0e,n),Z1t(r,n));return Y0e}function oEn(e,t,n){var r,a,o,f;e.a=n.b.d,De(t,326)?(a=l6(l(t,74),!1,!1),o=QN(a),r=new t_(e),to(o,r),dP(o,a),t.of((pi(),x3))!=null&&to(l(t.of(x3),75),r)):(f=l(t,422),f.rh(f.nh()+e.a.a),f.sh(f.oh()+e.a.b))}function cEn(e,t){var n,r,a;for(a=new bt,r=Rr(t.a,0);r.b!=r.d.c;)n=l(Br(r),65),n.c.g==e.g&&qe(Q(n.b,(Hc(),$d)))!==qe(Q(n.c,$d))&&!W5(new bn(null,new kn(a,16)),new cXe(n))&&$n(a.c,n);return Vs(a,new Mte),a}function Qpt(e,t,n){var r,a,o,f;return De(t,153)&&De(n,153)?(o=l(t,153),f=l(n,153),e.a[o.a][f.a]+e.a[f.a][o.a]):De(t,250)&&De(n,250)&&(r=l(t,250),a=l(n,250),r.a==a.a)?l(Q(a.a,(b0(),qx)),17).a:0}function Jpt(e,t){var n,r,a,o,f,g,w,E;for(E=ze(Ge(Q(t,(Nt(),tM)))),w=e[0].n.a+e[0].o.a+e[0].d.c+E,g=1;g=0?n:(g=eA(ma(new lt(f.c+f.b/2,f.d+f.a/2),new lt(o.c+o.b/2,o.d+o.a/2))),-(Tmt(o,f)-1)*g)}function lEn(e,t,n){var r;Is(new bn(null,(!n.a&&(n.a=new nt(cs,n,6,6)),new kn(n.a,16))),new dtt(e,t)),Is(new bn(null,(!n.n&&(n.n=new nt(ec,n,1,7)),new kn(n.n,16))),new gtt(e,t)),r=l(at(n,(pi(),x3)),75),r&&k7e(r,e,t)}function Hw(e,t,n){var r,a,o;if(o=g6((El(),io),e.Dh(),t),o)return Fo(),l(o,69).xk()||(o=rx(ic(io,o))),a=(r=e.Ih(o),l(r>=0?e.Lh(r,!0,!0):Hw(e,o,!0),160)),l(a,220).Sl(t,n);throw ue(new Yn(Ob+t.xe()+$fe))}function y9e(e,t,n,r){var a,o,f,g,w;if(a=e.d[t],a){if(o=a.g,w=a.i,r!=null){for(g=0;g=n&&(r=t,E=(w.c+w.a)/2,f=E-n,w.c<=E-n&&(a=new vae(w.c,f),pw(e,r++,a)),g=E+n,g<=w.a&&(o=new vae(g,w.a),Ey(r,e.c.length),x_(e.c,r,o)))}function t2t(e,t,n){var r,a,o,f,g,w;if(!t.dc()){for(a=new os,w=t.Kc();w.Ob();)for(g=l(w.Pb(),40),ki(e.a,pt(g.g),pt(n)),f=(r=Rr(new Hg(g).a.d,0),new C5(r));QI(f.a);)o=l(Br(f.a),65).c,Cs(a,o,a.c.b,a.c);t2t(e,a,n+1)}}function x9e(e){var t;if(!e.c&&e.g==null)e.d=e.bj(e.f),qr(e,e.d),t=e.d;else{if(e.g==null)return!0;if(e.i==0)return!1;t=l(e.g[e.i-1],51)}return t==e.b&&null.Vm>=null.Um()?(CU(e),x9e(e)):t.Ob()}function n2t(e){if(this.a=e,e.c.i.k==(Zn(),Us))this.c=e.c,this.d=l(Q(e.c.i,(ft(),Wc)),64);else if(e.d.i.k==Us)this.c=e.d,this.d=l(Q(e.d.i,(ft(),Wc)),64);else throw ue(new Yn("Edge "+e+" is not an external edge."))}function r2t(e,t){var n,r,a;a=e.b,e.b=t,e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,3,a,e.b)),t?t!=e&&(Fu(e,t.zb),Qoe(e,t.d),n=(r=t.c,r??t.zb),Zoe(e,n==null||vn(n,t.zb)?null:n)):(Fu(e,null),Qoe(e,0),Zoe(e,null))}function i2t(e,t){var n;this.e=(ww(),Xr(e),ww(),P8e(e)),this.c=(Xr(t),P8e(t)),Tye(this.e.Rd().dc()==this.c.Rd().dc()),this.d=w1t(this.e),this.b=w1t(this.c),n=Lm(wa,[dt,Rn],[5,1],5,[this.e.Rd().gc(),this.c.Rd().gc()],2),this.a=n,jwn(this)}function s2t(e){!C0e&&(C0e=cIn());var t=e.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g,function(n){return f2n(n)});return'"'+t+'"'}function k9e(e,t,n,r,a,o){var f,g,w,E,C;if(a!=0)for(qe(e)===qe(n)&&(e=e.slice(t,t+a),t=0),w=n,g=t,E=t+a;g=f)throw ue(new my(t,f));return a=n[t],f==1?r=null:(r=We(epe,r0e,424,f-1,0,1),pu(n,0,r,0,t),o=f-t-1,o>0&&pu(n,t+1,r,t,o)),PE(e,r),Apt(e,t,a),a}function o2t(e){var t,n;if(e.f){for(;e.n0?o=gx(n):o=BN(gx(n))),Hi(t,VT,o)}function mEn(e,t){var n;t.Ug("Partition preprocessing",1),n=l(yc(Fi(Dc(Fi(new bn(null,new kn(e.a,16)),new AZ),new LZ),new wj),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15),Is(n.Oc(),new t8),t.Vg()}function vEn(e,t){var n,r,a,o,f;for(f=e.j,t.a!=t.b&&Vs(f,new kS),a=f.c.length/2|0,r=0;r0&&lP(e,n,t),o):r.a!=null?(lP(e,t,n),-1):a.a!=null?(lP(e,n,t),1):0}function yEn(e,t){var n,r,a,o,f;for(a=t.b.b,e.a=We(mf,Qy,15,a,0,1),e.b=We(ih,pg,28,a,16,1),f=Rr(t.b,0);f.b!=f.d.c;)o=l(Br(f),40),e.a[o.g]=new os;for(r=Rr(t.a,0);r.b!=r.d.c;)n=l(Br(r),65),e.a[n.b.g].Fc(n),e.a[n.c.g].Fc(n)}function h2t(e,t){var n,r,a,o;e.Pj()?(n=e.Ej(),o=e.Qj(),++e.j,e.qj(n,e.Zi(n,t)),r=e.Ij(3,null,t,n,o),e.Mj()?(a=e.Nj(t,null),a?(a.nj(r),a.oj()):e.Jj(r)):e.Jj(r)):(tat(e,t),e.Mj()&&(a=e.Nj(t,null),a&&a.oj()))}function E9e(e,t,n){var r,a,o;e.Pj()?(o=e.Qj(),IN(e,t,n),r=e.Ij(3,null,n,t,o),e.Mj()?(a=e.Nj(n,null),e.Tj()&&(a=e.Uj(n,a)),a?(a.nj(r),a.oj()):e.Jj(r)):e.Jj(r)):(IN(e,t,n),e.Mj()&&(a=e.Nj(n,null),a&&a.oj()))}function EU(e,t){var n,r,a,o,f;for(f=Wu(e.e.Dh(),t),a=new X2,n=l(e.g,124),o=e.i;--o>=0;)r=n[o],f.am(r.Lk())&&qr(a,r);!awt(e,a)&&hh(e.e)&&xk(e,t.Jk()?db(e,6,t,(Cn(),_o),null,-1,!1):db(e,t.tk()?2:1,t,null,null,-1,!1))}function xEn(e,t){var n,r,a,o,f;return e.a==(zE(),VL)?!0:(o=t.a.c,n=t.a.c+t.a.b,!(t.j&&(r=t.A,f=r.c.c.a-r.o.a/2,a=o-(r.n.a+r.o.a),a>f)||t.q&&(r=t.C,f=r.c.c.a-r.o.a/2,a=r.n.a-n,a>f)))}function f2t(e){foe();var t,n,r,a,o,f,g;for(n=new e2,a=new G(e.e.b);a.a1?e.e*=ze(e.a):e.f/=ze(e.a),Hyn(e),Y5n(e),GSn(e),rt(e.b,(IA(),vK),e.g)}function b2t(e,t,n){var r,a,o,f,g,w;for(r=0,w=n,t||(r=n*(e.c.length-1),w*=-1),o=new G(e);o.a=0?e.Ah(null):e.Ph().Th(e,-1-t,null,null)),e.Bh(l(a,54),n),r&&r.oj(),e.vh()&&e.wh()&&n>-1&&Ni(e,new _a(e,9,n,o,a)),a):o}function S9e(e,t){var n,r,a,o,f;for(o=e.b.Ce(t),r=(n=e.a.get(o),n??We(wa,Rn,1,0,5,1)),f=0;f>5,a>=e.d)return e.e<0;if(n=e.a[a],t=1<<(t&31),e.e<0){if(r=Mft(e),a>16)),15).dd(o),g0&&(!(Ug(e.a.c)&&t.n.d)&&!(B5(e.a.c)&&t.n.b)&&(t.g.d+=b.Math.max(0,r/2-.5)),!(Ug(e.a.c)&&t.n.a)&&!(B5(e.a.c)&&t.n.c)&&(t.g.a-=r-1))}function C2t(e){var t,n,r,a,o;if(a=new bt,o=ymt(e,a),t=l(Q(e,(ft(),jl)),10),t)for(r=new G(t.j);r.a>t,o=e.m>>t|n<<22-t,a=e.l>>t|e.m<<22-t):t<44?(f=r?hp:0,o=n>>t-22,a=e.m>>t-22|n<<44-t):(f=r?hp:0,o=r?eh:0,a=n>>t-44),qu(a&eh,o&eh,f&hp)}function Gue(e){var t,n,r,a,o,f;for(this.c=new bt,this.d=e,r=gs,a=gs,t=ia,n=ia,f=Rr(e,0);f.b!=f.d.c;)o=l(Br(f),8),r=b.Math.min(r,o.a),a=b.Math.min(a,o.b),t=b.Math.max(t,o.a),n=b.Math.max(n,o.b);this.a=new ef(r,a,t-r,n-a)}function _2t(e,t){var n,r,a,o,f,g;for(o=new G(e.b);o.a0&&De(t,44)&&(e.a._j(),E=l(t,44),w=E.ld(),o=w==null?0:es(w),f=Qye(e.a,o),n=e.a.d[f],n)){for(r=l(n.g,379),C=n.i,g=0;g=2)for(n=a.Kc(),t=Ge(n.Pb());n.Ob();)o=t,t=Ge(n.Pb()),r=b.Math.min(r,(nr(t),t-(nr(o),o)));return r}function HEn(e,t){var n,r,a;for(a=new bt,r=Rr(t.a,0);r.b!=r.d.c;)n=l(Br(r),65),n.b.g==e.g&&!vn(n.b.c,DG)&&qe(Q(n.b,(Hc(),$d)))!==qe(Q(n.c,$d))&&!W5(new bn(null,new kn(a,16)),new uXe(n))&&$n(a.c,n);return Vs(a,new Nte),a}function VEn(e,t){var n,r,a;if(qe(t)===qe(Xr(e)))return!0;if(!De(t,15)||(r=l(t,15),a=e.gc(),a!=r.gc()))return!1;if(De(r,59)){for(n=0;n0&&(a=n),f=new G(e.f.e);f.a0?(t-=1,n-=1):r>=0&&a<0?(t+=1,n+=1):r>0&&a>=0?(t-=1,n+=1):(t+=1,n-=1),new ca(pt(t),pt(n))}function iTn(e,t){return e.ct.c?1:e.bt.b?1:e.a!=t.a?es(e.a)-es(t.a):e.d==(oA(),uM)&&t.d==cM?-1:e.d==cM&&t.d==uM?1:0}function N2t(e,t){var n,r,a,o,f;return o=t.a,o.c.i==t.b?f=o.d:f=o.c,o.c.i==t.b?r=o.c:r=o.d,a=S5n(e.a,f,r),a>0&&a0):a<0&&-a0):!1}function sTn(e,t,n,r){var a,o,f,g,w,E,C,L;for(a=(t-e.d)/e.c.c.length,o=0,e.a+=n,e.d=t,L=new G(e.c);L.a>24;return f}function oTn(e){if(e.ze()){var t=e.c;t.Ae()?e.o="["+t.n:t.ze()?e.o="["+t.xe():e.o="[L"+t.xe()+";",e.b=t.we()+"[]",e.k=t.ye()+"[]";return}var n=e.j,r=e.d;r=r.split("/"),e.o=Xce(".",[n,Xce("$",r)]),e.b=Xce(".",[n,Xce(".",r)]),e.k=r[r.length-1]}function cTn(e,t){var n,r,a,o,f;for(f=null,o=new G(e.e.a);o.a=0;t-=2)for(n=0;n<=t;n+=2)(e.b[n]>e.b[n+2]||e.b[n]===e.b[n+2]&&e.b[n+1]>e.b[n+3])&&(r=e.b[n+2],e.b[n+2]=e.b[n],e.b[n]=r,r=e.b[n+3],e.b[n+3]=e.b[n+1],e.b[n+1]=r);e.c=!0}}function hTn(e,t){var n,r,a,o,f,g,w,E,C;for(E=-1,C=0,f=e,g=0,w=f.length;g0&&++C;++E}return C}function g0(e){var t,n;return n=new Th(_m(e.Rm)),n.a+="@",hi(n,(t=es(e)>>>0,t.toString(16))),e.Vh()?(n.a+=" (eProxyURI: ",wu(n,e._h()),e.Kh()&&(n.a+=" eClass: ",wu(n,e.Kh())),n.a+=")"):e.Kh()&&(n.a+=" (eClass: ",wu(n,e.Kh()),n.a+=")"),n.a}function HA(e){var t,n,r,a;if(e.e)throw ue(new nc((Gg(R0e),phe+R0e.k+bhe)));for(e.d==(Js(),J1)&&UU(e,uc),n=new G(e.a.a);n.a>24}return n}function gTn(e,t,n){var r,a,o;if(a=l(Qo(e.i,t),314),!a)if(a=new yht(e.d,t,n),Q8(e.i,t,a),$8e(t))vhn(e.a,t.c,t.b,a);else switch(o=Q9n(t),r=l(Qo(e.p,o),252),o.g){case 1:case 3:a.j=!0,Xie(r,t.b,a);break;case 4:case 2:a.k=!0,Xie(r,t.c,a)}return a}function pTn(e,t){var n,r,a,o,f,g,w,E,C;for(w=eg(e.c-e.b&e.a.length-1),E=null,C=null,o=new nA(e);o.a!=o.b;)a=l(FV(o),10),n=(g=l(Q(a,(ft(),o1)),12),g?g.i:null),r=(f=l(Q(a,$f),12),f?f.i:null),(E!=n||C!=r)&&(m2t(w,t),E=n,C=r),$n(w.c,a);m2t(w,t)}function bTn(e,t,n,r){var a,o,f,g,w,E;if(g=new X2,w=Wu(e.e.Dh(),t),a=l(e.g,124),Fo(),l(t,69).xk())for(f=0;f=0)return a;for(o=1,g=new G(t.j);g.a=0)return a;for(o=1,g=new G(t.j);g.a0&&t.Ne((Sn(a-1,e.c.length),l(e.c[a-1],10)),o)>0;)rf(e,a,(Sn(a-1,e.c.length),l(e.c[a-1],10))),--a;Sn(a,e.c.length),e.c[a]=o}n.a=new Pr,n.b=new Pr}function mTn(e,t,n){var r,a,o,f,g,w,E,C;for(C=(r=l(t.e&&t.e(),9),new Zh(r,l(c0(r,r.length),9),0)),w=Gy(n,"[\\[\\]\\s,]+"),o=w,f=0,g=o.length;f=0?(t||(t=new h_,r>0&&Xo(t,(Ga(0,r,e.length),e.substr(0,r)))),t.a+="\\",Uk(t,n&Zs)):t&&Uk(t,n&Zs);return t?t.a:e}function wTn(e){var t,n,r;for(n=new G(e.a.a.b);n.a0&&(!(Ug(e.a.c)&&t.n.d)&&!(B5(e.a.c)&&t.n.b)&&(t.g.d-=b.Math.max(0,r/2-.5)),!(Ug(e.a.c)&&t.n.a)&&!(B5(e.a.c)&&t.n.c)&&(t.g.a+=b.Math.max(0,r-1)))}function H2t(e,t,n){var r,a;if((e.c-e.b&e.a.length-1)==2)t==(Ct(),Qn)||t==ar?(uV(l(wA(e),15),(Ih(),kg)),uV(l(wA(e),15),Gb)):(uV(l(wA(e),15),(Ih(),Gb)),uV(l(wA(e),15),kg));else for(a=new nA(e);a.a!=a.b;)r=l(FV(a),15),uV(r,n)}function yTn(e,t){var n,r,a,o,f,g,w;for(a=$k(new ywe(e)),g=new Ua(a,a.c.length),o=$k(new ywe(t)),w=new Ua(o,o.c.length),f=null;g.b>0&&w.b>0&&(n=(mr(g.b>0),l(g.a.Xb(g.c=--g.b),27)),r=(mr(w.b>0),l(w.a.Xb(w.c=--w.b),27)),n==r);)f=n;return f}function V2t(e,t,n){var r,a,o,f;Uot(e,t)>Uot(e,n)?(r=Oc(n,(Ct(),ar)),e.d=r.dc()?0:Tae(l(r.Xb(0),12)),f=Oc(t,er),e.b=f.dc()?0:Tae(l(f.Xb(0),12))):(a=Oc(n,(Ct(),er)),e.d=a.dc()?0:Tae(l(a.Xb(0),12)),o=Oc(t,ar),e.b=o.dc()?0:Tae(l(o.Xb(0),12)))}function U2t(e,t){var n,r,a,o;for(n=e.o.a,o=l(l($i(e.r,t),21),87).Kc();o.Ob();)a=l(o.Pb(),117),a.e.a=n*ze(Ge(a.b.of(pK))),a.e.b=(r=a.b,r.pf((pi(),rh))?r.ag()==(Ct(),Qn)?-r.Mf().b-ze(Ge(r.of(rh))):ze(Ge(r.of(rh))):r.ag()==(Ct(),Qn)?-r.Mf().b:0)}function xTn(e,t){var n,r,a,o;for(t.Ug("Self-Loop pre-processing",1),r=new G(e.a);r.ae.c));f++)a.a>=e.s&&(o<0&&(o=f),g=f);return w=(e.s+e.c)/2,o>=0&&(r=u_n(e,t,o,g),w=oln((Sn(r,t.c.length),l(t.c[r],339))),gEn(t,r,n)),w}function Wr(e,t,n){var r,a,o,f,g,w,E;for(f=(o=new CI,o),g7e(f,(nr(t),t)),E=(!f.b&&(f.b=new dh((Tn(),No),Yc,f)),f.b),w=1;w0&&sMn(this,a)}function F9e(e,t,n,r,a,o){var f,g,w;if(!a[t.a]){for(a[t.a]=!0,f=r,!f&&(f=new KH),vt(f.e,t),w=o[t.a].Kc();w.Ob();)g=l(w.Pb(),290),!(g.d==n||g.c==n)&&(g.c!=t&&F9e(e,g.c,t,f,a,o),g.d!=t&&F9e(e,g.d,t,f,a,o),vt(f.c,g),ra(f.d,g.b));return f}return null}function TTn(e){var t,n,r,a,o,f,g;for(t=0,a=new G(e.e);a.a=2}function CTn(e,t,n,r,a){var o,f,g,w,E,C;for(o=e.c.d.j,f=l(ff(n,0),8),C=1;C1||(t=rs(E0,he(le(Ko,1),it,95,0,[mp,T0])),yN(NH(t,e))>1)||(r=rs(S0,he(le(Ko,1),it,95,0,[Eg,qf])),yN(NH(r,e))>1))}function R9e(e,t,n){var r,a,o;for(o=new G(e.t);o.a0&&(r.b.n-=r.c,r.b.n<=0&&r.b.u>0&&ui(t,r.b));for(a=new G(e.i);a.a0&&(r.a.u-=r.c,r.a.u<=0&&r.a.n>0&&ui(n,r.a))}function CU(e){var t,n,r,a,o;if(e.g==null&&(e.d=e.bj(e.f),qr(e,e.d),e.c))return o=e.f,o;if(t=l(e.g[e.i-1],51),a=t.Pb(),e.e=t,n=e.bj(a),n.Ob())e.d=n,qr(e,n);else for(e.d=null;!t.Ob()&&(Ts(e.g,--e.i,null),e.i!=0);)r=l(e.g[e.i-1],51),t=r;return a}function _Tn(e,t){var n,r,a,o,f,g;if(r=t,a=r.Lk(),up(e.e,a)){if(a.Si()&&qH(e,a,r.md()))return!1}else for(g=Wu(e.e.Dh(),a),n=l(e.g,124),o=0;o1||n>1)return 2;return t+n==1?2:0}function Jl(e,t){var n,r,a,o,f,g;return o=e.a*hhe+e.b*1502,g=e.b*hhe+11,n=b.Math.floor(g*MP),o+=n,g-=n*cEe,o%=cEe,e.a=o,e.b=g,t<=24?b.Math.floor(e.a*m_e[t]):(a=e.a*(1<=2147483648&&(r-=4294967296),r)}function X2t(e,t,n){var r,a,o,f,g,w,E;for(o=new bt,E=new os,f=new os,YAn(e,E,f,t),_Mn(e,E,f,t,n),w=new G(e);w.ar.b.g&&$n(o.c,r);return o}function OTn(e,t,n){var r,a,o,f,g,w;for(g=e.c,f=(n.q?n.q:(Cn(),Cn(),mg)).vc().Kc();f.Ob();)o=l(f.Pb(),44),r=!_k(Fi(new bn(null,new kn(g,16)),new Wl(new att(t,o)))).Bd((Am(),zx)),r&&(w=o.md(),De(w,4)&&(a=H8e(w),a!=null&&(w=a)),t.qf(l(o.ld(),149),w))}function NTn(e,t,n){var r,a;if(qO(e.b),X0(e.b,(PN(),WW),(b_(),qB)),X0(e.b,YW,t.g),X0(e.b,XW,t.a),e.a=bP(e.b,t),n.Ug("Compaction by shrinking a tree",e.a.c.length),t.i.c.length>1)for(a=new G(e.a);a.a=0?e.Lh(r,!0,!0):Hw(e,o,!0),160)),l(a,220).Xl(t,n)}else throw ue(new Yn(Ob+t.xe()+kL))}function SU(e,t){var n,r,a,o,f;if(t){for(o=De(e.Cb,90)||De(e.Cb,102),f=!o&&De(e.Cb,331),r=new or((!t.a&&(t.a=new G_(t,Wo,t)),t.a));r.e!=r.i.gc();)if(n=l(gr(r),89),a=jU(n),o?De(a,90):f?De(a,156):a)return a;return o?(Tn(),Kf):(Tn(),td)}else return null}function PTn(e,t){var n,r,a,o;for(t.Ug("Resize child graph to fit parent.",1),r=new G(e.b);r.a=2*t&&vt(n,new vae(f[r-1]+t,f[r]-t));return n}function RTn(e,t,n){var r,a,o,f,g,w,E,C;if(n)for(o=n.a.length,r=new Dm(o),g=(r.b-r.a)*r.c<0?(sb(),tm):new cb(r);g.Ob();)f=l(g.Pb(),17),a=Jk(n,f.a),a&&(w=gmn(e,(E=(rb(),C=new jwe,C),t&&z9e(E,t),E),a),fE(w,Yg(a,Pd)),mU(a,w),h9e(a,w),wce(e,a,w))}function _U(e){var t,n,r,a,o,f;if(!e.j){if(f=new IS,t=qM,o=t.a.zc(e,t),o==null){for(r=new or(dc(e));r.e!=r.i.gc();)n=l(gr(r),29),a=_U(n),As(f,a),qr(f,n);t.a.Bc(e)!=null}Iy(f),e.j=new N5((l(Oe(tt((lb(),Vn).o),11),19),f.i),f.g),Yl(e).b&=-33}return e.j}function jTn(e){var t,n,r,a;if(e==null)return null;if(r=Tu(e,!0),a=eB.length,vn(r.substr(r.length-a,a),eB)){if(n=r.length,n==4){if(t=(Xn(0,r.length),r.charCodeAt(0)),t==43)return KPe;if(t==45)return wAt}else if(n==3)return KPe}return new Awe(r)}function $Tn(e){var t,n,r;return n=e.l,n&n-1||(r=e.m,r&r-1)||(t=e.h,t&t-1)||t==0&&r==0&&n==0?-1:t==0&&r==0&&n!=0?i7e(n):t==0&&r!=0&&n==0?i7e(r)+22:t!=0&&r==0&&n==0?i7e(t)+44:-1}function u6(e,t){var n,r,a,o,f;for(a=t.a&e.f,o=null,r=e.b[a];;r=r.b){if(r==t){o?o.b=t.b:e.b[a]=t.b;break}o=r}for(f=t.f&e.f,o=null,n=e.c[f];;n=n.d){if(n==t){o?o.d=t.d:e.c[f]=t.d;break}o=n}t.e?t.e.c=t.c:e.a=t.c,t.c?t.c.e=t.e:e.e=t.e,--e.i,++e.g}function zTn(e,t){var n;t.d?t.d.b=t.b:e.a=t.b,t.b?t.b.d=t.d:e.e=t.d,!t.e&&!t.c?(n=l(Lf(l(ax(e.b,t.a),260)),260),n.a=0,++e.c):(n=l(Lf(l(cr(e.b,t.a),260)),260),--n.a,t.e?t.e.c=t.c:n.b=l(Lf(t.c),511),t.c?t.c.e=t.e:n.c=l(Lf(t.e),511)),--e.d}function qTn(e){var t,n,r,a,o,f,g,w,E,C;for(n=e.o,t=e.p,f=Ii,a=lo,g=Ii,o=lo,E=0;E0),o.a.Xb(o.c=--o.b),by(o,a),mr(o.b3&&ag(e,0,t-3))}function VTn(e){var t,n,r,a;return qe(Q(e,(Nt(),p4)))===qe((rp(),A2))?!e.e&&qe(Q(e,TB))!==qe((vE(),vB)):(r=l(Q(e,Z1e),299),a=Rt(Bt(Q(e,ede)))||qe(Q(e,JL))===qe((dA(),mB)),t=l(Q(e,SMe),17).a,n=e.a.c.length,!a&&r!=(vE(),vB)&&(t==0||t>n))}function UTn(e){var t,n;for(n=0;n0);n++);if(n>0&&n0);t++);return t>0&&n>16!=6&&t){if(FE(e,t))throw ue(new Yn(EL+d2t(e)));r=null,e.Cb&&(r=(n=e.Db>>16,n>=0?lxe(e,r):e.Cb.Th(e,-1-n,null,r))),t&&(r=mx(t,e,6,r)),r=Wye(e,t,r),r&&r.oj()}else e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,6,t,t))}function AU(e,t){var n,r;if(t!=e.Cb||e.Db>>16!=3&&t){if(FE(e,t))throw ue(new Yn(EL+evt(e)));r=null,e.Cb&&(r=(n=e.Db>>16,n>=0?gxe(e,r):e.Cb.Th(e,-1-n,null,r))),t&&(r=mx(t,e,12,r)),r=Yye(e,t,r),r&&r.oj()}else e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,3,t,t))}function z9e(e,t){var n,r;if(t!=e.Cb||e.Db>>16!=9&&t){if(FE(e,t))throw ue(new Yn(EL+Jbt(e)));r=null,e.Cb&&(r=(n=e.Db>>16,n>=0?fxe(e,r):e.Cb.Th(e,-1-n,null,r))),t&&(r=mx(t,e,9,r)),r=Xye(e,t,r),r&&r.oj()}else e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,9,t,t))}function UE(e){var t,n,r,a,o;if(r=Of(e),o=e.j,o==null&&r)return e.Jk()?null:r.ik();if(De(r,156)){if(n=r.jk(),n&&(a=n.wi(),a!=e.i)){if(t=l(r,156),t.nk())try{e.g=a.ti(t,o)}catch(f){if(f=bs(f),De(f,82))e.g=null;else throw ue(f)}e.i=a}return e.g}return null}function ebt(e){var t;return t=new bt,vt(t,new B8(new lt(e.c,e.d),new lt(e.c+e.b,e.d))),vt(t,new B8(new lt(e.c,e.d),new lt(e.c,e.d+e.a))),vt(t,new B8(new lt(e.c+e.b,e.d+e.a),new lt(e.c+e.b,e.d))),vt(t,new B8(new lt(e.c+e.b,e.d+e.a),new lt(e.c,e.d+e.a))),t}function GTn(e){var t,n,r;if(e==null)return ul;try{return xc(e)}catch(a){if(a=bs(a),De(a,103))return t=a,r=_m(bh(e))+"@"+(n=(Vg(),q8e(e)>>>0),n.toString(16)),a6n(U3n(),(Dk(),"Exception during lenientFormat for "+r),t),"<"+r+" threw "+_m(t.Rm)+">";throw ue(a)}}function KTn(e,t,n){var r,a,o;for(o=t.a.ec().Kc();o.Ob();)a=l(o.Pb(),74),r=l(cr(e.b,a),272),!r&&(ds(cg(a))==ds(Eb(a))?NCn(e,a,n):cg(a)==ds(Eb(a))?cr(e.c,a)==null&&cr(e.b,Eb(a))!=null&&Ivt(e,a,n,!1):cr(e.d,a)==null&&cr(e.b,cg(a))!=null&&Ivt(e,a,n,!0))}function WTn(e,t){var n,r,a,o,f,g,w;for(a=e.Kc();a.Ob();)for(r=l(a.Pb(),10),g=new gu,Mc(g,r),la(g,(Ct(),ar)),rt(g,(ft(),oW),(Hn(),!0)),f=t.Kc();f.Ob();)o=l(f.Pb(),10),w=new gu,Mc(w,o),la(w,er),rt(w,oW,!0),n=new Tw,rt(n,oW,!0),po(n,g),Fa(n,w)}function YTn(e,t,n,r){var a,o,f,g;a=R1t(e,t,n),o=R1t(e,n,t),f=l(cr(e.c,t),118),g=l(cr(e.c,n),118),a1)for(t=hw((n=new Sm,++e.b,n),e.d),g=Rr(o,0);g.b!=g.d.c;)f=l(Br(g),125),p0(s0(i0(a0(r0(new _f,1),0),t),f))}function JTn(e,t,n){var r,a,o,f,g;for(n.Ug("Breaking Point Removing",1),e.a=l(Q(t,(Nt(),bp)),223),o=new G(t.b);o.a>16!=11&&t){if(FE(e,t))throw ue(new Yn(EL+oke(e)));r=null,e.Cb&&(r=(n=e.Db>>16,n>=0?pxe(e,r):e.Cb.Th(e,-1-n,null,r))),t&&(r=mx(t,e,10,r)),r=s4e(e,t,r),r&&r.oj()}else e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,11,t,t))}function ZTn(e){var t,n,r,a;for(r=new qm(new Sr(e.b).a);r.b;)n=Nw(r),a=l(n.ld(),12),t=l(n.md(),10),rt(t,(ft(),zi),a),rt(a,jl,t),rt(a,xB,(Hn(),!0)),la(a,l(Q(t,Wc),64)),Q(t,Wc),rt(a.i,(Nt(),Ms),(Ra(),sC)),l(Q(eo(a.i),Lu),21).Fc((Ho(),$T))}function eCn(e,t,n){var r,a,o,f,g,w;if(o=0,f=0,e.c)for(w=new G(e.d.i.j);w.ao.a?-1:a.aw){for(C=e.d,e.d=We(vPe,_Se,66,2*w+4,0,1),o=0;o=9223372036854776e3?(iE(),WSe):(a=!1,e<0&&(a=!0,e=-e),r=0,e>=Zm&&(r=ua(e/Zm),e-=r*Zm),n=0,e>=Lx&&(n=ua(e/Lx),e-=n*Lx),t=ua(e),o=qu(t,n,r),a&&yce(o),o)}function hCn(e){var t,n,r,a,o;if(o=new bt,Vu(e.b,new Jd(o)),e.b.c.length=0,o.c.length!=0){for(t=(Sn(0,o.c.length),l(o.c[0],82)),n=1,r=o.c.length;n=-t&&r==t?new ca(pt(n-1),pt(r)):new ca(pt(n),pt(r-1))}function rbt(){return vo(),he(le(EOn,1),it,81,0,[PAe,IAe,D6,f1e,eLe,DK,zK,l4,JAe,HAe,XAe,u4,ZAe,$Ae,tLe,SAe,PK,d1e,LK,RK,rLe,FK,_Ae,QAe,iLe,jK,nLe,MK,FAe,WAe,KAe,qK,MAe,AK,OK,LAe,LT,UAe,zAe,YAe,zL,OAe,DAe,GAe,qAe,NK,$K,AAe,BK,VAe,IK,RAe,BAe,gB,_K,jAe,NAe])}function gCn(e,t,n){e.d=0,e.b=0,t.k==(Zn(),Au)&&n.k==Au&&l(Q(t,(ft(),zi)),10)==l(Q(n,zi),10)&&($oe(t).j==(Ct(),Qn)?V2t(e,t,n):V2t(e,n,t)),t.k==Au&&n.k==Aa?$oe(t).j==(Ct(),Qn)?e.d=1:e.b=1:n.k==Au&&t.k==Aa&&($oe(n).j==(Ct(),Qn)?e.b=1:e.d=1),J6n(e,t,n)}function pCn(e){var t,n,r,a,o,f,g,w,E,C,L;return L=jxe(e),t=e.a,w=t!=null,w&&zk(L,"category",e.a),a=ZI(new br(e.d)),f=!a,f&&(E=new $p,e1(L,"knownOptions",E),n=new oQe(E),to(new br(e.d),n)),o=ZI(e.g),g=!o,g&&(C=new $p,e1(L,"supportedFeatures",C),r=new cQe(C),to(e.g,r)),L}function bCn(e){var t,n,r,a,o,f,g,w,E;for(r=!1,t=336,n=0,o=new Grt(e.length),g=e,w=0,E=g.length;w>16!=7&&t){if(FE(e,t))throw ue(new Yn(EL+lpt(e)));r=null,e.Cb&&(r=(n=e.Db>>16,n>=0?hxe(e,r):e.Cb.Th(e,-1-n,null,r))),t&&(r=l(t,54).Rh(e,1,oF,r)),r=J4e(e,t,r),r&&r.oj()}else e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,7,t,t))}function ibt(e,t){var n,r;if(t!=e.Cb||e.Db>>16!=3&&t){if(FE(e,t))throw ue(new Yn(EL+c1t(e)));r=null,e.Cb&&(r=(n=e.Db>>16,n>=0?dxe(e,r):e.Cb.Th(e,-1-n,null,r))),t&&(r=l(t,54).Rh(e,0,uF,r)),r=Z4e(e,t,r),r&&r.oj()}else e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,3,t,t))}function Que(e,t){GE();var n,r,a,o,f,g,w,E,C;return t.d>e.d&&(g=e,e=t,t=g),t.d<63?iSn(e,t):(f=(e.d&-2)<<4,E=v6e(e,f),C=v6e(t,f),r=mle(e,sx(E,f)),a=mle(t,sx(C,f)),w=Que(E,C),n=Que(r,a),o=Que(mle(E,r),mle(a,C)),o=Tle(Tle(o,w),n),o=sx(o,f),w=sx(w,f<<1),Tle(Tle(w,o),n))}function p2(){p2=U,gde=new M5(cyt,0),fDe=new M5("LONGEST_PATH",1),dDe=new M5("LONGEST_PATH_SOURCE",2),dde=new M5("COFFMAN_GRAHAM",3),hDe=new M5($he,4),gDe=new M5("STRETCH_WIDTH",5),CW=new M5("MIN_WIDTH",6),WT=new M5("BF_MODEL_ORDER",7),YT=new M5("DF_MODEL_ORDER",8)}function vCn(e,t,n){var r,a,o,f,g;for(f=TA(e,n),g=We(wg,m2,10,t.length,0,1),r=0,o=f.Kc();o.Ob();)a=l(o.Pb(),12),Rt(Bt(Q(a,(ft(),xB))))&&(g[r++]=l(Q(a,jl),10));if(r=0;o+=n?1:-1)f=f|t.c.lg(w,o,n,r&&!Rt(Bt(Q(t.j,(ft(),jb))))&&!Rt(Bt(Q(t.j,(ft(),j6))))),f=f|t.q.ug(w,o,n),f=f|Ubt(e,w[o],n,r);return na(e.c,t),f}function DU(e,t,n){var r,a,o,f,g,w,E,C,L,B;for(C=Tct(e.j),L=0,B=C.length;L1&&(e.a=!0),Qdn(l(n.b,68),Oi(Ja(l(t.b,68).c),md(ma(Ja(l(n.b,68).a),l(t.b,68).a),a))),Dot(e,t),sbt(e,n)}function abt(e){var t,n,r,a,o,f,g;for(o=new G(e.a.a);o.a0&&o>0?f.p=t++:r>0?f.p=n++:o>0?f.p=a++:f.p=n++}Cn(),Vs(e.j,new W9)}function ECn(e){var t,n;n=null,t=l(jt(e.g,0),18);do{if(n=t.d.i,ns(n,(ft(),$f)))return l(Q(n,$f),12).i;if(n.k!=(Zn(),Ps)&&jr(new hr(dr(qs(n).a.Kc(),new j))))t=l(xr(new hr(dr(qs(n).a.Kc(),new j))),18);else if(n.k!=Ps)return null}while(n&&n.k!=(Zn(),Ps));return n}function TCn(e,t){var n,r,a,o,f,g,w,E,C;for(g=t.j,f=t.g,w=l(jt(g,g.c.length-1),113),C=(Sn(0,g.c.length),l(g.c[0],113)),E=vue(e,f,w,C),o=1;oE&&(w=n,C=a,E=r);t.a=C,t.c=w}function CCn(e,t,n){var r,a,o,f,g,w,E;for(E=new Kp(new UYe(e)),f=he(le(F8t,1),I3t,12,0,[t,n]),g=0,w=f.length;gw-e.b&&gw-e.a&&g0?o.a?(g=o.b.Mf().a,n>g&&(a=(n-g)/2,o.d.b=a,o.d.c=a)):o.d.c=e.s+n:W_(e.u)&&(r=$xe(o.b),r.c<0&&(o.d.b=-r.c),r.c+r.b>o.b.Mf().a&&(o.d.c=r.c+r.b-o.b.Mf().a))}function qCn(e,t){var n,r,a,o,f;f=new bt,n=t;do o=l(cr(e.b,n),131),o.B=n.c,o.D=n.d,$n(f.c,o),n=l(cr(e.k,n),18);while(n);return r=(Sn(0,f.c.length),l(f.c[0],131)),r.j=!0,r.A=l(r.d.a.ec().Kc().Pb(),18).c.i,a=l(jt(f,f.c.length-1),131),a.q=!0,a.C=l(a.d.a.ec().Kc().Pb(),18).d.i,f}function HCn(e){var t,n;if(t=l(e.a,17).a,n=l(e.b,17).a,t>=0){if(t==n)return new ca(pt(-t-1),pt(-t-1));if(t==-n)return new ca(pt(-t),pt(n+1))}return b.Math.abs(t)>b.Math.abs(n)?t<0?new ca(pt(-t),pt(n)):new ca(pt(-t),pt(n+1)):new ca(pt(t+1),pt(n))}function VCn(e){var t,n;n=l(Q(e,(Nt(),Qu)),171),t=l(Q(e,(ft(),hv)),311),n==(hf(),$b)?(rt(e,Qu,EB),rt(e,hv,(ep(),F6))):n==d4?(rt(e,Qu,EB),rt(e,hv,(ep(),Ux))):t==(ep(),F6)?(rt(e,Qu,$b),rt(e,hv,wB)):t==Ux&&(rt(e,Qu,d4),rt(e,hv,wB))}function IU(){IU=U,IB=new pte,XEt=fi(new Xs,(uo(),bu),(vo(),LK)),ZEt=yl(fi(new Xs,bu,FK),mc,BK),eTt=Td(Td(v_(yl(fi(new Xs,y0,zK),mc,$K),_u),jK),qK),QEt=yl(fi(fi(fi(new Xs,vg,DK),_u,OK),_u,LT),mc,IK),JEt=yl(fi(fi(new Xs,_u,LT),_u,AK),mc,_K)}function GA(){GA=U,rTt=fi(yl(new Xs,(uo(),mc),(vo(),RAe)),bu,LK),oTt=Td(Td(v_(yl(fi(new Xs,y0,zK),mc,$K),_u),jK),qK),iTt=yl(fi(fi(fi(new Xs,vg,DK),_u,OK),_u,LT),mc,IK),aTt=fi(fi(new Xs,bu,FK),mc,BK),sTt=yl(fi(fi(new Xs,_u,LT),_u,AK),mc,_K)}function UCn(e,t,n,r,a){var o,f;(!Do(t)&&t.c.i.c==t.d.i.c||!uft(Ic(he(le(Ea,1),dt,8,0,[a.i.n,a.n,a.a])),n))&&!Do(t)&&(t.c==a?Pk(t.a,0,new Eo(n)):ui(t.a,new Eo(n)),r&&!W0(e.a,n)&&(f=l(Q(t,(Nt(),cc)),75),f||(f=new bl,rt(t,cc,f)),o=new Eo(n),Cs(f,o,f.c.b,f.c),na(e.a,o)))}function ubt(e,t){var n,r,a,o;for(o=Yr(mo(fg,ig(Yr(mo(t==null?0:es(t),dg)),15))),n=o&e.b.length-1,a=null,r=e.b[n];r;a=r,r=r.a)if(r.d==o&&yd(r.i,t))return a?a.a=r.a:e.b[n]=r.a,RJe(l(Lf(r.c),604),l(Lf(r.f),604)),WI(l(Lf(r.b),227),l(Lf(r.e),227)),--e.f,++e.e,!0;return!1}function GCn(e){var t,n;for(n=new hr(dr(ka(e).a.Kc(),new j));jr(n);)if(t=l(xr(n),18),t.c.i.k!=(Zn(),cu))throw ue(new Vp(jhe+HN(e)+"' has its layer constraint set to FIRST, but has at least one incoming edge that does not come from a FIRST_SEPARATE node. That must not happen."))}function KCn(e,t,n){var r,a,o,f,g,w,E;if(a=d1t(e.Db&254),a==0)e.Eb=n;else{if(a==1)g=We(wa,Rn,1,2,5,1),o=mue(e,t),o==0?(g[0]=n,g[1]=e.Eb):(g[0]=e.Eb,g[1]=n);else for(g=We(wa,Rn,1,a+1,5,1),f=jm(e.Eb),r=2,w=0,E=0;r<=128;r<<=1)r==t?g[E++]=n:e.Db&r&&(g[E++]=f[w++]);e.Eb=g}e.Db|=t}function lbt(e,t,n){var r,a,o,f;for(this.b=new bt,a=0,r=0,f=new G(e);f.a0&&(o=l(jt(this.b,0),176),a+=o.o,r+=o.p),a*=2,r*=2,t>1?a=ua(b.Math.ceil(a*t)):r=ua(b.Math.ceil(r/t)),this.a=new I8e(a,r)}function hbt(e,t,n,r,a,o){var f,g,w,E,C,L,B,z,V,J,te,fe;for(C=r,t.j&&t.o?(z=l(cr(e.f,t.A),60),J=z.d.c+z.d.b,--C):J=t.a.c+t.a.b,L=a,n.q&&n.o?(z=l(cr(e.f,n.C),60),E=z.d.c,++L):E=n.a.c,te=E-J,w=b.Math.max(2,L-C),g=te/w,V=J+g,B=C;B=0;f+=a?1:-1){for(g=t[f],w=r==(Ct(),ar)?a?Oc(g,r):lf(Oc(g,r)):a?lf(Oc(g,r)):Oc(g,r),o&&(e.c[g.p]=w.gc()),L=w.Kc();L.Ob();)C=l(L.Pb(),12),e.d[C.p]=E++;ra(n,w)}}function dbt(e,t,n){var r,a,o,f,g,w,E,C;for(o=ze(Ge(e.b.Kc().Pb())),E=ze(Ge(V3n(t.b))),r=md(Ja(e.a),E-n),a=md(Ja(t.a),n-o),C=Oi(r,a),md(C,1/(E-o)),this.a=C,this.b=new bt,g=!0,f=e.b.Kc(),f.Pb();f.Ob();)w=ze(Ge(f.Pb())),g&&w-n>wfe&&(this.b.Fc(n),g=!1),this.b.Fc(w);g&&this.b.Fc(n)}function WCn(e){var t,n,r,a;if(f_n(e,e.n),e.d.c.length>0){for(u_(e.c);L9e(e,l(re(new G(e.e.a)),125))>5,t&=31,r>=e.d)return e.e<0?(Cd(),w6t):(Cd(),BL);if(o=e.d-r,a=We(Vr,di,28,o+1,15,1),j9n(a,o,e.a,r,t),e.e<0){for(n=0;n0&&e.a[n]<<32-t){for(n=0;n=0?!1:(n=g6((El(),io),a,t),n?(r=n.Ik(),(r>1||r==-1)&&kw(ic(io,n))!=3):!0)):!1}function JCn(e,t,n,r){var a,o,f,g,w;return g=bc(l(Oe((!t.b&&(t.b=new Ln(_r,t,4,7)),t.b),0),84)),w=bc(l(Oe((!t.c&&(t.c=new Ln(_r,t,5,8)),t.c),0),84)),ds(g)==ds(w)||Ly(w,g)?null:(f=WO(t),f==n?r:(o=l(cr(e.a,f),10),o&&(a=o.e,a)?a:null))}function ZCn(e,t,n){var r,a,o,f,g;for(n.Ug("Longest path to source layering",1),e.a=t,g=e.a.a,e.b=We(Vr,di,28,g.c.length,15,1),r=0,f=new G(g);f.a0&&(n[0]+=e.d,f-=n[0]),n[2]>0&&(n[2]+=e.d,f-=n[2]),o=b.Math.max(0,f),n[1]=b.Math.max(n[1],f),y6e(e,$u,a.c+r.b+n[0]-(n[1]-f)/2,n),t==$u&&(e.c.b=o,e.c.c=a.c+r.b+(o-f)/2)}function Ebt(){this.c=We(Na,Zo,28,(Ct(),he(le(Oo,1),au,64,0,[Pc,Qn,ar,Dr,er])).length,15,1),this.b=We(Na,Zo,28,he(le(Oo,1),au,64,0,[Pc,Qn,ar,Dr,er]).length,15,1),this.a=We(Na,Zo,28,he(le(Oo,1),au,64,0,[Pc,Qn,ar,Dr,er]).length,15,1),E3e(this.c,gs),E3e(this.b,ia),E3e(this.a,ia)}function Eu(e,t,n){var r,a,o,f;if(t<=n?(a=t,o=n):(a=n,o=t),r=0,e.b==null)e.b=We(Vr,di,28,2,15,1),e.b[0]=a,e.b[1]=o,e.c=!0;else{if(r=e.b.length,e.b[r-1]+1==a){e.b[r-1]=o;return}f=We(Vr,di,28,r+2,15,1),pu(e.b,0,f,0,r),e.b=f,e.b[r-1]>=a&&(e.c=!1,e.a=!1),e.b[r++]=a,e.b[r]=o,e.c||c6(e)}}function sSn(e,t,n){var r,a,o,f,g,w,E;for(E=t.d,e.a=new Bu(E.c.length),e.c=new Pr,g=new G(E);g.a=0?e.Lh(E,!1,!0):Hw(e,n,!1),61));e:for(o=L.Kc();o.Ob();){for(a=l(o.Pb(),58),C=0;C1;)Vy(a,a.i-1);return r}function Cbt(e,t){var n,r,a,o,f,g,w;for(n=new z5,o=new G(e.b);o.ae.d[f.p]&&(n+=f6e(e.b,o),gb(e.a,pt(o)));for(;!l_(e.a);)U6e(e.b,l(X8(e.a),17).a)}return n}function hSn(e){var t,n,r,a,o,f,g,w,E;for(e.a=new i4e,E=0,a=0,r=new G(e.i.b);r.ag.d&&(C=g.d+g.a+E));n.c.d=C,t.a.zc(n,t),w=b.Math.max(w,n.c.d+n.c.a)}return w}function Ho(){Ho=U,eW=new uy("COMMENTS",0),vf=new uy("EXTERNAL_PORTS",1),UL=new uy("HYPEREDGES",2),tW=new uy("HYPERNODES",3),$T=new uy("NON_FREE_PORTS",4),B6=new uy("NORTH_SOUTH_PORTS",5),GL=new uy(X3t,6),RT=new uy("CENTER_LABELS",7),jT=new uy("END_LABELS",8),nW=new uy("PARTITIONS",9)}function dSn(e,t,n,r,a){return r<0?(r=o6(e,a,he(le(zt,1),dt,2,6,[$le,zle,qle,Hle,_x,Vle,Ule,Gle,Kle,Wle,Yle,Xle]),t),r<0&&(r=o6(e,a,he(le(zt,1),dt,2,6,["Jan","Feb","Mar","Apr",_x,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),r<0?!1:(n.k=r,!0)):r>0?(n.k=r-1,!0):!1}function gSn(e,t,n,r,a){return r<0?(r=o6(e,a,he(le(zt,1),dt,2,6,[$le,zle,qle,Hle,_x,Vle,Ule,Gle,Kle,Wle,Yle,Xle]),t),r<0&&(r=o6(e,a,he(le(zt,1),dt,2,6,["Jan","Feb","Mar","Apr",_x,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),r<0?!1:(n.k=r,!0)):r>0?(n.k=r-1,!0):!1}function pSn(e,t,n,r,a,o){var f,g,w,E;if(g=32,r<0){if(t[0]>=e.length||(g=co(e,t[0]),g!=43&&g!=45)||(++t[0],r=kU(e,t),r<0))return!1;g==45&&(r=-r)}return g==32&&t[0]-n==2&&a.b==2&&(w=new Qz,E=w.q.getFullYear()-Lb+Lb-80,f=E%100,o.a=r==f,r+=(E/100|0)*100+(r=0?kb(e):J_(kb(r2(e)))),FL[t]=Aq(l0(e,t),0)?kb(l0(e,t)):J_(kb(r2(l0(e,t)))),e=mo(e,5);for(;t=E&&(w=r);w&&(C=b.Math.max(C,w.a.o.a)),C>B&&(L=E,B=C)}return L}function xSn(e){var t,n,r,a,o,f,g;for(o=new Kp(l(Xr(new Wh),50)),g=ia,n=new G(e.d);n.akyt?Vs(w,e.b):r<=kyt&&r>Eyt?Vs(w,e.d):r<=Eyt&&r>Tyt?Vs(w,e.c):r<=Tyt&&Vs(w,e.a),o=Mbt(e,w,o);return a}function Dbt(e,t,n,r){var a,o,f,g,w,E;for(a=(r.c+r.a)/2,Ch(t.j),ui(t.j,a),Ch(n.e),ui(n.e,a),E=new QJe,g=new G(e.f);g.a1,g&&(r=new lt(a,n.b),ui(t.a,r)),fA(t.a,he(le(Ea,1),dt,8,0,[B,L]))}function J9e(e,t,n){var r,a;for(t=48;n--)GM[n]=n-48<<24>>24;for(r=70;r>=65;r--)GM[r]=r-65+10<<24>>24;for(a=102;a>=97;a--)GM[a]=a-97+10<<24>>24;for(o=0;o<10;o++)LY[o]=48+o&Zs;for(e=10;e<=15;e++)LY[e]=65+e-10&Zs}function CSn(e,t){t.Ug("Process graph bounds",1),rt(e,(Qi(),Bde),fO(uce(xy(new bn(null,new kn(e.b,16)),new zte)))),rt(e,Fde,fO(uce(xy(new bn(null,new kn(e.b,16)),new qte)))),rt(e,rIe,fO(cce(xy(new bn(null,new kn(e.b,16)),new Hte)))),rt(e,iIe,fO(cce(xy(new bn(null,new kn(e.b,16)),new Vte)))),t.Vg()}function SSn(e){var t,n,r,a,o;a=l(Q(e,(Nt(),bv)),21),o=l(Q(e,xW),21),n=new lt(e.f.a+e.d.b+e.d.c,e.f.b+e.d.d+e.d.a),t=new Eo(n),a.Hc((mh(),A4))&&(r=l(Q(e,qT),8),o.Hc((Zl(),aC))&&(r.a<=0&&(r.a=20),r.b<=0&&(r.b=20)),t.a=b.Math.max(n.a,r.a),t.b=b.Math.max(n.b,r.b)),Rt(Bt(Q(e,ade)))||nLn(e,n,t)}function _Sn(e,t){var n,r,a,o;for(o=Oc(t,(Ct(),Dr)).Kc();o.Ob();)r=l(o.Pb(),12),n=l(Q(r,(ft(),jl)),10),n&&p0(s0(i0(a0(r0(new _f,0),.1),e.i[t.p].d),e.i[n.p].a));for(a=Oc(t,Qn).Kc();a.Ob();)r=l(a.Pb(),12),n=l(Q(r,(ft(),jl)),10),n&&p0(s0(i0(a0(r0(new _f,0),.1),e.i[n.p].d),e.i[t.p].a))}function Zue(e){var t,n,r,a,o,f;if(!e.c){if(f=new Qc,t=qM,o=t.a.zc(e,t),o==null){for(r=new or(du(e));r.e!=r.i.gc();)n=l(gr(r),89),a=jU(n),De(a,90)&&As(f,Zue(l(a,29))),qr(f,n);t.a.Bc(e)!=null,t.a.gc()==0}k5n(f),Iy(f),e.c=new N5((l(Oe(tt((lb(),Vn).o),15),19),f.i),f.g),Yl(e).b&=-33}return e.c}function eke(e){var t;if(e.c!=10)throw ue(new ri(ai((Jr(),VG))));switch(t=e.a,t){case 110:t=10;break;case 114:t=13;break;case 116:t=9;break;case 92:case 124:case 46:case 94:case 45:case 63:case 42:case 43:case 123:case 125:case 40:case 41:case 91:case 93:break;default:throw ue(new ri(ai((Jr(),bf))))}return t}function Pbt(e){var t,n,r,a,o;if(e.l==0&&e.m==0&&e.h==0)return"0";if(e.h==SP&&e.m==0&&e.l==0)return"-9223372036854775808";if(e.h>>19)return"-"+Pbt(xE(e));for(n=e,r="";!(n.l==0&&n.m==0&&n.h==0);){if(a=Loe(JU),n=Nke(n,a,!0),t=""+rZe(Nb),!(n.l==0&&n.m==0&&n.h==0))for(o=9-t.length;o>0;o--)t="0"+t;r=t+r}return r}function ASn(e){var t,n,r,a,o,f,g;for(t=!1,n=0,a=new G(e.d.b);a.a=e.a||!Bxe(t,n))return-1;if(Zk(l(r.Kb(t),20)))return 1;for(a=0,f=l(r.Kb(t),20).Kc();f.Ob();)if(o=l(f.Pb(),18),w=o.c.i==t?o.d.i:o.c.i,g=tke(e,w,n,r),g==-1||(a=b.Math.max(a,g),a>e.c-1))return-1;return a+1}function Bbt(e,t){var n,r,a,o,f,g;if(qe(t)===qe(e))return!0;if(!De(t,15)||(r=l(t,15),g=e.gc(),r.gc()!=g))return!1;if(f=r.Kc(),e.Yi()){for(n=0;n0){if(e._j(),t!=null){for(o=0;o>24;case 97:case 98:case 99:case 100:case 101:case 102:return e-97+10<<24>>24;case 65:case 66:case 67:case 68:case 69:case 70:return e-65+10<<24>>24;default:throw ue(new gd("Invalid hexadecimal"))}}function PU(){PU=U,j_e=new L5("SPIRAL",0),P_e=new L5("LINE_BY_LINE",1),B_e=new L5("MANHATTAN",2),N_e=new L5("JITTER",3),z0e=new L5("QUADRANTS_LINE_BY_LINE",4),R_e=new L5("QUADRANTS_MANHATTAN",5),F_e=new L5("QUADRANTS_JITTER",6),O_e=new L5("COMBINE_LINE_BY_LINE_MANHATTAN",7),I_e=new L5("COMBINE_JITTER_MANHATTAN",8)}function Rbt(e,t,n,r){var a,o,f,g,w,E;for(w=Tue(e,n),E=Tue(t,n),a=!1;w&&E&&(r||C7n(w,E,n));)f=Tue(w,n),g=Tue(E,n),uN(t),uN(e),o=w.c,Cle(w,!1),Cle(E,!1),n?(Fy(t,E.p,o),t.p=E.p,Fy(e,w.p+1,o),e.p=w.p):(Fy(e,w.p,o),e.p=w.p,Fy(t,E.p+1,o),t.p=E.p),Va(w,null),Va(E,null),w=f,E=g,a=!0;return a}function jbt(e){switch(e.g){case 0:return new Gre;case 1:return new XS;case 3:return new fet;case 4:return new zee;case 5:return new zrt;case 6:return new jI;case 2:return new YS;case 7:return new az;case 8:return new RI;default:throw ue(new Yn("No implementation is available for the layerer "+(e.f!=null?e.f:""+e.g)))}}function NSn(e,t,n,r){var a,o,f,g,w;for(a=!1,o=!1,g=new G(r.j);g.a=t.length)throw ue(new tc("Greedy SwitchDecider: Free layer not in graph."));this.c=t[e],this.e=new IO(r),ice(this.e,this.c,(Ct(),er)),this.i=new IO(r),ice(this.i,this.c,ar),this.f=new ist(this.c),this.a=!o&&a.i&&!a.s&&this.c[0].k==(Zn(),Us),this.a&&W9n(this,e,t.length)}function zbt(e,t){var n,r,a,o,f,g;o=!e.B.Hc((Zl(),sF)),f=e.B.Hc(Gge),e.a=new _1t(f,o,e.c),e.n&&O5e(e.a.n,e.n),Xie(e.g,(t1(),$u),e.a),t||(r=new DA(1,o,e.c),r.n.a=e.k,Q8(e.p,(Ct(),Qn),r),a=new DA(1,o,e.c),a.n.d=e.k,Q8(e.p,Dr,a),g=new DA(0,o,e.c),g.n.c=e.k,Q8(e.p,er,g),n=new DA(0,o,e.c),n.n.b=e.k,Q8(e.p,ar,n))}function BSn(e){var t,n,r;switch(t=l(Q(e.d,(Nt(),bp)),223),t.g){case 2:n=TIn(e);break;case 3:n=(r=new bt,Is(Fi(fc(Dc(Dc(new bn(null,new kn(e.d.b,16)),new dee),new gee),new pee),new wS),new xYe(r)),r);break;default:throw ue(new nc("Compaction not supported for "+t+" edges."))}GLn(e,n),to(new br(e.g),new wYe(e))}function FSn(e,t){var n,r,a,o,f,g,w;if(t.Ug("Process directions",1),n=l(Q(e,(Hc(),y3)),88),n!=(Js(),Q1))for(a=Rr(e.b,0);a.b!=a.d.c;){switch(r=l(Br(a),40),g=l(Q(r,(Qi(),PB)),17).a,w=l(Q(r,BB),17).a,n.g){case 4:w*=-1;break;case 1:o=g,g=w,w=o;break;case 2:f=g,g=-w,w=f}rt(r,PB,pt(g)),rt(r,BB,pt(w))}t.Vg()}function RSn(e,t){var n;return n=new Bs,t&&pc(n,l(cr(e.a,oF),96)),De(t,422)&&pc(n,l(cr(e.a,cF),96)),De(t,366)?(pc(n,l(cr(e.a,ec),96)),n):(De(t,84)&&pc(n,l(cr(e.a,_r),96)),De(t,207)?(pc(n,l(cr(e.a,Ai),96)),n):De(t,193)?(pc(n,l(cr(e.a,Hl),96)),n):(De(t,326)&&pc(n,l(cr(e.a,js),96)),n))}function jSn(e){var t,n,r,a,o,f,g,w;for(w=new xut,g=new G(e.a);g.a0&&t=0)return!1;if(t.p=n.b,vt(n.e,t),a==(Zn(),Aa)||a==Au){for(f=new G(t.j);f.ae.d[g.p]&&(n+=f6e(e.b,o),gb(e.a,pt(o)))):++f;for(n+=e.b.d*f;!l_(e.a);)U6e(e.b,l(X8(e.a),17).a)}return n}function Qbt(e){var t,n,r,a,o,f;return o=0,t=Of(e),t.kk()&&(o|=4),e.Bb&Sl&&(o|=2),De(e,102)?(n=l(e,19),a=Ro(n),n.Bb&eu&&(o|=32),a&&(yr(ky(a)),o|=8,f=a.t,(f>1||f==-1)&&(o|=16),a.Bb&eu&&(o|=64)),n.Bb&Io&&(o|=r4),o|=m0):De(t,469)?o|=512:(r=t.kk(),r&&r.i&1&&(o|=256)),e.Bb&512&&(o|=128),o}function QSn(e,t){var n;return e.f==spe?(n=kw(ic((El(),io),t)),e.e?n==4&&t!=(kx(),u9)&&t!=(kx(),c9)&&t!=(kx(),ape)&&t!=(kx(),ope):n==2):e.d&&(e.d.Hc(t)||e.d.Hc(rx(ic((El(),io),t)))||e.d.Hc(g6((El(),io),e.b,t)))?!0:e.f&&q9e((El(),e.f),HO(ic(io,t)))?(n=kw(ic(io,t)),e.e?n==4:n==2):!1}function JSn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z;for(B=-1,z=0,E=e,C=0,L=E.length;C0&&++z;++B}return z}function ZSn(e,t,n,r){var a,o,f,g,w,E,C,L;return f=l(at(n,(pi(),n9)),8),w=f.a,C=f.b+e,a=b.Math.atan2(C,w),a<0&&(a+=iv),a+=t,a>iv&&(a-=iv),g=l(at(r,n9),8),E=g.a,L=g.b+e,o=b.Math.atan2(L,E),o<0&&(o+=iv),o+=t,o>iv&&(o-=iv),A1(),f0(1e-10),b.Math.abs(a-o)<=1e-10||a==o||isNaN(a)&&isNaN(o)?0:ao?1:uw(isNaN(a),isNaN(o))}function nle(e){var t,n,r,a,o,f,g;for(g=new Pr,r=new G(e.a.b);r.a=e.o)throw ue(new Bwe);g=t>>5,f=t&31,o=l0(1,Yr(l0(f,1))),a?e.n[n][g]=Q0(e.n[n][g],o):e.n[n][g]=va(e.n[n][g],O4e(o)),o=l0(o,1),r?e.n[n][g]=Q0(e.n[n][g],o):e.n[n][g]=va(e.n[n][g],O4e(o))}catch(w){throw w=bs(w),De(w,333)?ue(new tc(Ehe+e.o+"*"+e.p+The+t+Co+n+Che)):ue(w)}}function n_n(e,t,n,r){var a,o,f,g,w,E,C,L,B;for(B=new Kp(new VYe(e)),g=he(le(wg,1),m2,10,0,[t,n]),w=0,E=g.length;w0&&(r=(!e.n&&(e.n=new nt(ec,e,1,7)),l(Oe(e.n,0),135)).a,!r||hi(hi((t.a+=' "',t),r),'"'))),hi(rw(hi(rw(hi(rw(hi(rw((t.a+=" (",t),e.i),","),e.j)," | "),e.g),","),e.f),")"),t.a)}function Jbt(e){var t,n,r;return e.Db&64?Pue(e):(t=new Th(uSe),n=e.k,n?hi(hi((t.a+=' "',t),n),'"'):(!e.n&&(e.n=new nt(ec,e,1,7)),e.n.i>0&&(r=(!e.n&&(e.n=new nt(ec,e,1,7)),l(Oe(e.n,0),135)).a,!r||hi(hi((t.a+=' "',t),r),'"'))),hi(rw(hi(rw(hi(rw(hi(rw((t.a+=" (",t),e.i),","),e.j)," | "),e.g),","),e.f),")"),t.a)}function s_n(e,t){var n,r,a,o,f;for(t==(yA(),Cde)&&JN(l($i(e.a,(Ry(),bB)),15)),a=l($i(e.a,(Ry(),bB)),15).Kc();a.Ob();)switch(r=l(a.Pb(),105),n=l(jt(r.j,0),113).d.j,o=new Ol(r.j),Vs(o,new Rj),t.g){case 2:Lue(e,o,n,(Ow(),Rb),1);break;case 1:case 0:f=UTn(o),Lue(e,new Zp(o,0,f),n,(Ow(),Rb),0),Lue(e,new Zp(o,f,o.c.length),n,Rb,1)}}function ile(e,t){var n,r,a,o,f,g,w;if(t==null||t.length==0)return null;if(a=l(xu(e.a,t),143),!a){for(r=(g=new gi(e.b).a.vc().Kc(),new fs(g));r.a.Ob();)if(n=(o=l(r.a.Pb(),44),l(o.md(),143)),f=n.c,w=t.length,vn(f.substr(f.length-w,w),t)&&(t.length==f.length||co(f,f.length-t.length-1)==46)){if(a)return null;a=n}a&&rc(e.a,t,a)}return a}function a_n(e,t){var n,r,a,o;return n=new as,r=l(yc(fc(new bn(null,new kn(e.f,16)),n),Sy(new yt,new ji,new qn,new Un,he(le(oc,1),it,108,0,[(Fl(),i4),Ec]))),21),a=r.gc(),r=l(yc(fc(new bn(null,new kn(t.f,16)),n),Sy(new yt,new ji,new qn,new Un,he(le(oc,1),it,108,0,[i4,Ec]))),21),o=r.gc(),aa.p?(la(o,Dr),o.d&&(g=o.o.b,t=o.a.b,o.a.b=g-t)):o.j==Dr&&a.p>e.p&&(la(o,Qn),o.d&&(g=o.o.b,t=o.a.b,o.a.b=-(g-t)));break}return a}function uP(e,t,n,r,a){var o,f,g,w,E,C,L;if(!(De(t,207)||De(t,366)||De(t,193)))throw ue(new Yn("Method only works for ElkNode-, ElkLabel and ElkPort-objects."));return f=e.a/2,w=t.i+r-f,C=t.j+a-f,E=w+t.g+e.a,L=C+t.f+e.a,o=new bl,ui(o,new lt(w,C)),ui(o,new lt(w,L)),ui(o,new lt(E,L)),ui(o,new lt(E,C)),g=new Gue(o),pc(g,t),n&&ki(e.b,t,g),g}function KE(e,t,n){var r,a,o,f,g,w,E,C,L,B;for(o=new lt(t,n),C=new G(e.a);C.a1,g&&(r=new lt(a,n.b),ui(t.a,r)),fA(t.a,he(le(Ea,1),dt,8,0,[B,L]))}function Nf(){Nf=U,AW=new ly(Id,0),AB=new ly("NIKOLOV",1),LB=new ly("NIKOLOV_PIXEL",2),xDe=new ly("NIKOLOV_IMPROVED",3),kDe=new ly("NIKOLOV_IMPROVED_PIXEL",4),yDe=new ly("DUMMYNODE_PERCENTAGE",5),EDe=new ly("NODECOUNT_PERCENTAGE",6),LW=new ly("NO_BOUNDARY",7),v3=new ly("MODEL_ORDER_LEFT_TO_RIGHT",8),x4=new ly("MODEL_ORDER_RIGHT_TO_LEFT",9)}function b_n(e){var t,n,r,a,o;for(r=e.length,t=new h_,o=0;o=40,f&&mAn(e),SLn(e),WCn(e),n=m1t(e),r=0;n&&r0&&ui(e.f,o)):(e.c[f]-=E+1,e.c[f]<=0&&e.a[f]>0&&ui(e.e,o))))}function hmt(e,t,n,r){var a,o,f,g,w,E,C;for(w=new lt(n,r),ma(w,l(Q(t,(Qi(),QT)),8)),C=Rr(t.b,0);C.b!=C.d.c;)E=l(Br(C),40),Oi(E.e,w),ui(e.b,E);for(g=l(yc(V5e(new bn(null,new kn(t.a,16))),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15).Kc();g.Ob();){for(f=l(g.Pb(),65),o=Rr(f.a,0);o.b!=o.d.c;)a=l(Br(o),8),a.a+=w.a,a.b+=w.b;ui(e.a,f)}}function bke(e,t){var n,r,a,o;if(0<(De(e,16)?l(e,16).gc():Xg(e.Kc()))){if(a=t,1=0&&wo*2?(C=new hV(L),E=wl(f)/gh(f),w=Lle(C,t,new A8,n,r,a,E),Oi(Y0(C.e),w),L.c.length=0,o=0,$n(L.c,C),$n(L.c,f),o=wl(C)*gh(C)+wl(f)*gh(f)):($n(L.c,f),o+=wl(f)*gh(f));return L}function dmt(e,t){var n,r,a,o,f,g;if(g=l(Q(t,(Nt(),Ms)),101),g==(Ra(),Tg)||g==Mu)for(a=new lt(t.f.a+t.d.b+t.d.c,t.f.b+t.d.d+t.d.a).b,f=new G(e.a);f.an?t:n;E<=L;++E)E==n?g=r++:(o=a[E],C=V.am(o.Lk()),E==t&&(w=E==L&&!C?r-1:r),C&&++r);return B=l(AA(e,t,n),76),g!=w&&xk(e,new sN(e.e,7,f,pt(g),z.md(),w)),B}}else return l(Hue(e,t,n),76);return l(AA(e,t,n),76)}function B_n(e,t){var n,r,a,o,f,g,w;for(t.Ug("Port order processing",1),w=l(Q(e,(Nt(),ZMe)),430),r=new G(e.b);r.a=0&&(g=M7n(e,f),!(g&&(E<22?w.l|=1<>>1,f.m=C>>>1|(L&1)<<21,f.l=B>>>1|(C&1)<<21,--E;return n&&yce(w),o&&(r?(Nb=xE(e),a&&(Nb=Jft(Nb,(iE(),YSe)))):Nb=qu(e.l,e.m,e.h)),w}function j_n(e,t){var n,r,a,o,f,g,w,E,C,L;for(E=e.e[t.c.p][t.p]+1,w=t.c.a.c.length+1,g=new G(e.a);g.a0&&(Xn(0,e.length),e.charCodeAt(0)==45||(Xn(0,e.length),e.charCodeAt(0)==43))?1:0,r=f;rn)throw ue(new gd(Yw+e+'"'));return g}function $_n(e){var t,n,r,a,o,f,g;for(f=new os,o=new G(e.a);o.a1)&&t==1&&l(e.a[e.b],10).k==(Zn(),cu)?Tx(l(e.a[e.b],10),(Ih(),kg)):r&&(!n||(e.c-e.b&e.a.length-1)>1)&&t==1&&l(e.a[e.c-1&e.a.length-1],10).k==(Zn(),cu)?Tx(l(e.a[e.c-1&e.a.length-1],10),(Ih(),Gb)):(e.c-e.b&e.a.length-1)==2?(Tx(l(wA(e),10),(Ih(),kg)),Tx(l(wA(e),10),Gb)):pTn(e,a),l6e(e)}function H_n(e,t,n){var r,a,o,f,g;for(o=0,a=new or((!e.a&&(e.a=new nt(Ai,e,10,11)),e.a));a.e!=a.i.gc();)r=l(gr(a),27),f="",(!r.n&&(r.n=new nt(ec,r,1,7)),r.n).i==0||(f=l(Oe((!r.n&&(r.n=new nt(ec,r,1,7)),r.n),0),135).a),g=new xce(o++,t,f),pc(g,r),rt(g,(Qi(),gM),r),g.e.b=r.j+r.f/2,g.f.a=b.Math.max(r.g,1),g.e.a=r.i+r.g/2,g.f.b=b.Math.max(r.f,1),ui(t.b,g),ju(n.f,r,g)}function V_n(e){var t,n,r,a,o;r=l(Q(e,(ft(),zi)),27),o=l(at(r,(Nt(),bv)),181).Hc((mh(),Cv)),e.e||(a=l(Q(e,Lu),21),t=new lt(e.f.a+e.d.b+e.d.c,e.f.b+e.d.d+e.d.a),a.Hc((Ho(),vf))?(Hi(r,Ms,(Ra(),Mu)),Gw(r,t.a,t.b,!1,!0)):Rt(Bt(at(r,ade)))||Gw(r,t.a,t.b,!0,!0)),o?Hi(r,bv,un(Cv)):Hi(r,bv,(n=l(K0(BM),9),new Zh(n,l(c0(n,n.length),9),0)))}function mke(e,t,n){var r,a,o,f;if(t[0]>=e.length)return n.o=0,!0;switch(co(e,t[0])){case 43:a=1;break;case 45:a=-1;break;default:return n.o=0,!0}if(++t[0],o=t[0],f=kU(e,t),f==0&&t[0]==o)return!1;if(t[0]g&&(g=a,C.c.length=0),a==g&&vt(C,new ca(n.c.i,n)));Cn(),Vs(C,e.c),pw(e.b,w.p,C)}}function W_n(e,t){var n,r,a,o,f,g,w,E,C;for(f=new G(t.b);f.ag&&(g=a,C.c.length=0),a==g&&vt(C,new ca(n.d.i,n)));Cn(),Vs(C,e.c),pw(e.f,w.p,C)}}function Y_n(e,t){var n,r,a,o,f,g,w,E;if(E=Bt(Q(t,(Hc(),MTt))),E==null||(nr(E),E)){for(yEn(e,t),a=new bt,w=Rr(t.b,0);w.b!=w.d.c;)f=l(Br(w),40),n=i9e(e,f,null),n&&(pc(n,t),$n(a.c,n));if(e.a=null,e.b=null,a.c.length>1)for(r=new G(a);r.a=0&&g!=n&&(o=new _a(e,1,g,f,null),r?r.nj(o):r=o),n>=0&&(o=new _a(e,1,n,g==n?f:null,t),r?r.nj(o):r=o)),r}function bmt(e){var t,n,r;if(e.b==null){if(r=new Up,e.i!=null&&(Xo(r,e.i),r.a+=":"),e.f&256){for(e.f&256&&e.a!=null&&(dpn(e.i)||(r.a+="//"),Xo(r,e.a)),e.d!=null&&(r.a+="/",Xo(r,e.d)),e.f&16&&(r.a+="/"),t=0,n=e.j.length;tB?!1:(L=(w=ZA(r,B,!1),w.a),C+g+L<=t.b&&(aN(n,o-n.s),n.c=!0,aN(r,o-n.s),qN(r,n.s,n.t+n.d+g),r.k=!0,C7e(n.q,r),z=!0,a&&(bV(t,r),r.j=t,e.c.length>f&&(UN((Sn(f,e.c.length),l(e.c[f],186)),r),(Sn(f,e.c.length),l(e.c[f],186)).a.c.length==0&&t2(e,f)))),z)}function nAn(e,t){var n,r,a,o,f,g;if(t.Ug("Partition midprocessing",1),a=new Cw,Is(Fi(new bn(null,new kn(e.a,16)),new vj),new cYe(a)),a.d!=0){for(g=l(yc(K5e((o=a.i,new bn(null,(o||(a.i=new q5(a,a.c))).Nc()))),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15),r=g.Kc(),n=l(r.Pb(),17);r.Ob();)f=l(r.Pb(),17),WTn(l($i(a,n),21),l($i(a,f),21)),n=f;t.Vg()}}function wmt(e,t,n){var r,a,o,f,g,w,E,C;if(t.p==0){for(t.p=1,f=n,f||(a=new bt,o=(r=l(K0(Oo),9),new Zh(r,l(c0(r,r.length),9),0)),f=new ca(a,o)),l(f.a,15).Fc(t),t.k==(Zn(),Us)&&l(f.b,21).Fc(l(Q(t,(ft(),Wc)),64)),w=new G(t.j);w.a0){if(a=l(e.Ab.g,2033),t==null){for(o=0;on.s&&gf)return Ct(),ar;break;case 4:case 3:if(C<0)return Ct(),Qn;if(C+n>o)return Ct(),Dr}return w=(E+g/2)/f,r=(C+n/2)/o,w+r<=1&&w-r<=0?(Ct(),er):w+r>=1&&w-r>=0?(Ct(),ar):r<.5?(Ct(),Qn):(Ct(),Dr)}function oAn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J;for(n=!1,C=ze(Ge(Q(t,(Nt(),m3)))),V=Ab*C,a=new G(t.b);a.aw+V&&(J=L.g+B.g,B.a=(B.g*B.a+L.g*L.a)/J,B.g=J,L.f=B,n=!0)),o=g,L=B;return n}function Emt(e,t,n,r,a,o,f){var g,w,E,C,L,B;for(B=new $8,E=t.Kc();E.Ob();)for(g=l(E.Pb(),853),L=new G(g.Rf());L.a0?g.a?(E=g.b.Mf().b,a>E&&(e.v||g.c.d.c.length==1?(f=(a-E)/2,g.d.d=f,g.d.a=f):(n=l(jt(g.c.d,0),187).Mf().b,r=(n-E)/2,g.d.d=b.Math.max(0,r),g.d.a=a-r-E))):g.d.a=e.t+a:W_(e.u)&&(o=$xe(g.b),o.d<0&&(g.d.d=-o.d),o.d+o.a>g.b.Mf().b&&(g.d.a=o.d+o.a-g.b.Mf().b))}function b0(){b0=U,qx=new Ha((pi(),XB),pt(1)),kK=new Ha(Ev,80),n8t=new Ha(ANe,5),G7t=new Ha(Z6,lT),e8t=new Ha(zge,pt(1)),t8t=new Ha(qge,(Hn(),!0)),nAe=new lw(50),J7t=new Ha(_2,nAe),Z_e=WB,rAe=_M,K7t=new Ha(Dge,!1),tAe=YB,X7t=C4,Q7t=Ub,Y7t=kv,W7t=r7,Z7t=S4,eAe=(Xxe(),j7t),Z0e=H7t,xK=R7t,J0e=$7t,iAe=q7t,s8t=AM,a8t=aY,i8t=QB,r8t=sY,sAe=(dx(),L4),new Ha(i9,sAe)}function lAn(e,t){var n;switch(gN(e)){case 6:return Ia(t);case 7:return fy(t);case 8:return hy(t);case 3:return Array.isArray(t)&&(n=gN(t),!(n>=14&&n<=16));case 11:return t!=null&&typeof t===Ole;case 12:return t!=null&&(typeof t===wP||typeof t==Ole);case 0:return iue(t,e.__elementTypeId$);case 2:return Rae(t)&&t.Tm!==xe;case 1:return Rae(t)&&t.Tm!==xe||iue(t,e.__elementTypeId$);default:return!0}}function Tmt(e,t){var n,r,a,o;return r=b.Math.min(b.Math.abs(e.c-(t.c+t.b)),b.Math.abs(e.c+e.b-t.c)),o=b.Math.min(b.Math.abs(e.d-(t.d+t.a)),b.Math.abs(e.d+e.a-t.d)),n=b.Math.abs(e.c+e.b/2-(t.c+t.b/2)),n>e.b/2+t.b/2||(a=b.Math.abs(e.d+e.a/2-(t.d+t.a/2)),a>e.a/2+t.a/2)?1:n==0&&a==0?0:n==0?o/a+1:a==0?r/n+1:b.Math.min(r/n,o/a)+1}function hAn(e,t){var n,r,a,o,f,g,w;for(o=0,g=0,w=0,a=new G(e.f.e);a.a0&&e.d!=(lA(),n1e)&&(g+=f*(r.d.a+e.a[t.a][r.a]*(t.d.a-r.d.a)/n)),n>0&&e.d!=(lA(),e1e)&&(w+=f*(r.d.b+e.a[t.a][r.a]*(t.d.b-r.d.b)/n)));switch(e.d.g){case 1:return new lt(g/o,t.d.b);case 2:return new lt(t.d.a,w/o);default:return new lt(g/o,w/o)}}function Cmt(e){var t,n,r,a,o,f;for(n=(!e.a&&(e.a=new Ys(qh,e,5)),e.a).i+2,f=new Bu(n),vt(f,new lt(e.j,e.k)),Is(new bn(null,(!e.a&&(e.a=new Ys(qh,e,5)),new kn(e.a,16))),new NXe(f)),vt(f,new lt(e.b,e.c)),t=1;t0&&(SN(w,!1,(Js(),uc)),SN(w,!0,vc)),Vu(t.g,new jet(e,n)),ki(e.g,t,n)}function Amt(){Amt=U;var e;for(r_e=he(le(Vr,1),di,28,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]),A0e=We(Vr,di,28,37,15,1),b6t=he(le(Vr,1),di,28,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]),i_e=We(nm,ahe,28,37,14,1),e=2;e<=36;e++)A0e[e]=ua(b.Math.pow(e,r_e[e])),i_e[e]=KN(EP,A0e[e])}function fAn(e){var t;if((!e.a&&(e.a=new nt(cs,e,6,6)),e.a).i!=1)throw ue(new Yn(n4t+(!e.a&&(e.a=new nt(cs,e,6,6)),e.a).i));return t=new bl,TN(l(Oe((!e.b&&(e.b=new Ln(_r,e,4,7)),e.b),0),84))&&Ka(t,bwt(e,TN(l(Oe((!e.b&&(e.b=new Ln(_r,e,4,7)),e.b),0),84)),!1)),TN(l(Oe((!e.c&&(e.c=new Ln(_r,e,5,8)),e.c),0),84))&&Ka(t,bwt(e,TN(l(Oe((!e.c&&(e.c=new Ln(_r,e,5,8)),e.c),0),84)),!0)),t}function Lmt(e,t){var n,r,a,o,f;for(t.d?a=e.a.c==(xd(),w3)?ka(t.b):qs(t.b):a=e.a.c==(xd(),T2)?ka(t.b):qs(t.b),o=!1,r=new hr(dr(a.a.Kc(),new j));jr(r);)if(n=l(xr(r),18),f=Rt(e.a.f[e.a.g[t.b.p].p]),!(!f&&!Do(n)&&n.c.i.c==n.d.i.c)&&!(Rt(e.a.n[e.a.g[t.b.p].p])||Rt(e.a.n[e.a.g[t.b.p].p]))&&(o=!0,W0(e.b,e.a.g[f7n(n,t.b).p])))return t.c=!0,t.a=n,t;return t.c=o,t.a=null,t}function wke(e,t,n){var r,a,o,f,g,w,E;if(r=n.gc(),r==0)return!1;if(e.Pj())if(w=e.Qj(),A8e(e,t,n),f=r==1?e.Ij(3,null,n.Kc().Pb(),t,w):e.Ij(5,null,n,t,w),e.Mj()){for(g=r<100?null:new nb(r),o=t+r,a=t;a0){for(f=0;f>16==-15&&e.Cb.Yh()&&qoe(new Foe(e.Cb,9,13,n,e.c,f2(Xl(l(e.Cb,62)),e))):De(e.Cb,90)&&e.Db>>16==-23&&e.Cb.Yh()&&(t=e.c,De(t,90)||(t=(Tn(),Kf)),De(n,90)||(n=(Tn(),Kf)),qoe(new Foe(e.Cb,9,10,n,t,f2(du(l(e.Cb,29)),e)))))),e.c}function pAn(e,t,n){var r,a,o,f,g,w,E,C,L;for(n.Ug("Hyperedge merging",1),jEn(e,t),w=new Ua(t.b,0);w.b0,g=HV(t,o),Iye(n?g.b:g.g,t),Z5(g).c.length==1&&Cs(r,g,r.c.b,r.c),a=new ca(o,t),gb(e.o,a),al(e.e.a,o))}function Bmt(e,t){var n,r,a,o,f,g,w;return r=b.Math.abs(mH(e.b).a-mH(t.b).a),g=b.Math.abs(mH(e.b).b-mH(t.b).b),a=0,w=0,n=1,f=1,r>e.b.b/2+t.b.b/2&&(a=b.Math.min(b.Math.abs(e.b.c-(t.b.c+t.b.b)),b.Math.abs(e.b.c+e.b.b-t.b.c)),n=1-a/r),g>e.b.a/2+t.b.a/2&&(w=b.Math.min(b.Math.abs(e.b.d-(t.b.d+t.b.a)),b.Math.abs(e.b.d+e.b.a-t.b.d)),f=1-w/g),o=b.Math.min(n,f),(1-o)*b.Math.sqrt(r*r+g*g)}function vAn(e){var t,n,r,a;for(Ale(e,e.e,e.f,(Sw(),Hb),!0,e.c,e.i),Ale(e,e.e,e.f,Hb,!1,e.c,e.i),Ale(e,e.e,e.f,K6,!0,e.c,e.i),Ale(e,e.e,e.f,K6,!1,e.c,e.i),gAn(e,e.c,e.e,e.f,e.i),r=new Ua(e.i,0);r.b=65;n--)nd[n]=n-65<<24>>24;for(r=122;r>=97;r--)nd[r]=r-97+26<<24>>24;for(a=57;a>=48;a--)nd[a]=a-48+52<<24>>24;for(nd[43]=62,nd[47]=63,o=0;o<=25;o++)N2[o]=65+o&Zs;for(f=26,w=0;f<=51;++f,w++)N2[f]=97+w&Zs;for(e=52,g=0;e<=61;++e,g++)N2[e]=48+g&Zs;N2[62]=43,N2[63]=47}function Fmt(e,t){var n,r,a,o,f,g;return a=y7e(e),g=y7e(t),a==g?e.e==t.e&&e.a<54&&t.a<54?e.ft.f?1:0:(r=e.e-t.e,n=(e.d>0?e.d:b.Math.floor((e.a-1)*Vwt)+1)-(t.d>0?t.d:b.Math.floor((t.a-1)*Vwt)+1),n>r+1?a:n0&&(f=K5(f,Wmt(r))),K1t(o,f))):aE&&(B=0,z+=w+t,w=0),KE(f,B,z),n=b.Math.max(n,B+C.a),w=b.Math.max(w,C.b),B+=C.a+t;return new lt(n+t,z+w+t)}function Eke(e,t){var n,r,a,o,f,g,w;if(!M1(e))throw ue(new nc(t4t));if(r=M1(e),o=r.g,a=r.f,o<=0&&a<=0)return Ct(),Pc;switch(g=e.i,w=e.j,t.g){case 2:case 1:if(g<0)return Ct(),er;if(g+e.g>o)return Ct(),ar;break;case 4:case 3:if(w<0)return Ct(),Qn;if(w+e.f>a)return Ct(),Dr}return f=(g+e.g/2)/o,n=(w+e.f/2)/a,f+n<=1&&f-n<=0?(Ct(),er):f+n>=1&&f-n>=0?(Ct(),ar):n<.5?(Ct(),Qn):(Ct(),Dr)}function xAn(e,t,n,r,a){var o,f;if(o=bo(va(t[0],Vo),va(r[0],Vo)),e[0]=Yr(o),o=bw(o,32),n>=a){for(f=1;f0&&(a.b[f++]=0,a.b[f++]=o.b[0]-1),t=1;t0&&(H(w,w.d-a.d),a.c==(J0(),qb)&&N(w,w.a-a.d),w.d<=0&&w.i>0&&Cs(t,w,t.c.b,t.c)));for(o=new G(e.f);o.a0&&(q(g,g.i-a.d),a.c==(J0(),qb)&&$(g,g.b-a.d),g.i<=0&&g.d>0&&Cs(n,g,n.c.b,n.c)))}function TAn(e,t,n,r,a){var o,f,g,w,E,C,L,B,z;for(Cn(),Vs(e,new tk),f=PO(e),z=new bt,B=new bt,g=null,w=0;f.b!=0;)o=l(f.b==0?null:(mr(f.b!=0),af(f,f.a.a)),163),!g||wl(g)*gh(g)/21&&(w>wl(g)*gh(g)/2||f.b==0)&&(L=new hV(B),C=wl(g)/gh(g),E=Lle(L,t,new A8,n,r,a,C),Oi(Y0(L.e),E),g=L,$n(z.c,L),w=0,B.c.length=0));return ra(z,B),z}function pu(e,t,n,r,a){Vg();var o,f,g,w,E,C,L;if(d5e(e,"src"),d5e(n,"dest"),L=bh(e),w=bh(n),I4e((L.i&4)!=0,"srcType is not an array"),I4e((w.i&4)!=0,"destType is not an array"),C=L.c,f=w.c,I4e(C.i&1?C==f:(f.i&1)==0,"Array types don't match"),lyn(e,t,n,r,a),!(C.i&1)&&L!=w)if(E=jm(e),o=jm(n),qe(e)===qe(n)&&tr;)Ts(o,g,E[--t]);else for(g=r+a;r0),r.a.Xb(r.c=--r.b),L>B+w&&ph(r);for(f=new G(z);f.a0),r.a.Xb(r.c=--r.b)}}function SAn(){Di();var e,t,n,r,a,o;if(upe)return upe;for(e=new _h(4),Ky(e,_b(p0e,!0)),nL(e,_b("M",!0)),nL(e,_b("C",!0)),o=new _h(4),r=0;r<11;r++)Eu(o,r,r);return t=new _h(4),Ky(t,_b("M",!0)),Eu(t,4448,4607),Eu(t,65438,65439),a=new B_(2),Qm(a,e),Qm(a,WM),n=new B_(2),n.Jm(oH(o,_b("L",!0))),n.Jm(t),n=new Ty(3,n),n=new f5e(a,n),upe=n,upe}function Gy(e,t){var n,r,a,o,f,g,w,E;for(n=new RegExp(t,"g"),w=We(zt,dt,2,0,6,1),r=0,E=e,o=null;;)if(g=n.exec(E),g==null||E==""){w[r]=E;break}else f=g.index,w[r]=(Ga(0,f,E.length),E.substr(0,f)),E=tf(E,f+g[0].length,E.length),n.lastIndex=0,o==E&&(w[r]=(Ga(0,1,E.length),E.substr(0,1)),E=(Xn(1,E.length+1),E.substr(1))),o=E,++r;if(e.length>0){for(a=w.length;a>0&&w[a-1]=="";)--a;a0&&(L-=r[0]+e.c,r[0]+=e.c),r[2]>0&&(L-=r[2]+e.c),r[1]=b.Math.max(r[1],L),hH(e.a[1],n.c+t.b+r[0]-(r[1]-L)/2,r[1]);for(o=e.a,g=0,E=o.length;g0?(e.n.c.length-1)*e.i:0,r=new G(e.n);r.a1)for(r=Rr(a,0);r.b!=r.d.c;)for(n=l(Br(r),235),o=0,w=new G(n.e);w.a0&&(t[0]+=e.c,L-=t[0]),t[2]>0&&(L-=t[2]+e.c),t[1]=b.Math.max(t[1],L),fH(e.a[1],r.d+n.d+t[0]-(t[1]-L)/2,t[1]);else for(V=r.d+n.d,z=r.a-n.d-n.a,f=e.a,w=0,C=f.length;w0||Fw(a.b.d,e.b.d+e.b.a)==0&&r.b<0||Fw(a.b.d+a.b.a,e.b.d)==0&&r.b>0){g=0;break}}else g=b.Math.min(g,Bpt(e,a,r));g=b.Math.min(g,zmt(e,o,g,r))}return g}function dP(e,t){var n,r,a,o,f,g,w;if(e.b<2)throw ue(new Yn("The vector chain must contain at least a source and a target point."));for(a=(mr(e.b!=0),l(e.a.a.c,8)),kO(t,a.a,a.b),w=new q8((!t.a&&(t.a=new Ys(qh,t,5)),t.a)),f=Rr(e,1);f.a=0&&o!=n))throw ue(new Yn(WP));for(a=0,w=0;wze(L1(f.g,f.d[0]).a)?(mr(w.b>0),w.a.Xb(w.c=--w.b),by(w,f),a=!0):g.e&&g.e.gc()>0&&(o=(!g.e&&(g.e=new bt),g.e).Mc(t),E=(!g.e&&(g.e=new bt),g.e).Mc(n),(o||E)&&((!g.e&&(g.e=new bt),g.e).Fc(f),++f.c));a||$n(r.c,f)}function OAn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe;return L=e.a.i+e.a.g/2,B=e.a.i+e.a.g/2,V=t.i+t.g/2,te=t.j+t.f/2,g=new lt(V,te),E=l(at(t,(pi(),n9)),8),E.a=E.a+L,E.b=E.b+B,o=(g.b-E.b)/(g.a-E.a),r=g.b-o*g.a,J=n.i+n.g/2,fe=n.j+n.f/2,w=new lt(J,fe),C=l(at(n,n9),8),C.a=C.a+L,C.b=C.b+B,f=(w.b-C.b)/(w.a-C.a),a=w.b-f*w.a,z=(r-a)/(f-o),E.a>>0,"0"+t.toString(16)),r="\\x"+tf(n,n.length-2,n.length)):e>=Io?(n=(t=e>>>0,"0"+t.toString(16)),r="\\v"+tf(n,n.length-6,n.length)):r=""+String.fromCharCode(e&Zs)}return r}function Umt(e){var t,n,r;if(P5(l(Q(e,(Nt(),Ms)),101)))for(n=new G(e.j);n.a=t.o&&n.f<=t.f||t.a*.5<=n.f&&t.a*1.5>=n.f){if(f=l(jt(t.n,t.n.c.length-1),209),f.e+f.d+n.g+a<=r&&(o=l(jt(t.n,t.n.c.length-1),209),o.f-e.f+n.f<=e.b||e.a.c.length==1))return y8e(t,n),!0;if(t.s+n.g<=r&&(t.t+t.d+n.f+a<=e.b||e.a.c.length==1))return vt(t.b,n),g=l(jt(t.n,t.n.c.length-1),209),vt(t.n,new PH(t.s,g.f+g.a+t.i,t.i)),exe(l(jt(t.n,t.n.c.length-1),209),n),jmt(t,n),!0}return!1}function Kmt(e,t,n){var r,a,o,f;return e.Pj()?(a=null,o=e.Qj(),r=e.Ij(1,f=Uoe(e,t,n),n,t,o),e.Mj()&&!(e.Yi()&&f!=null?Pi(f,n):qe(f)===qe(n))?(f!=null&&(a=e.Oj(f,a)),a=e.Nj(n,a),e.Tj()&&(a=e.Wj(f,n,a)),a?(a.nj(r),a.oj()):e.Jj(r)):(e.Tj()&&(a=e.Wj(f,n,a)),a?(a.nj(r),a.oj()):e.Jj(r)),f):(f=Uoe(e,t,n),e.Mj()&&!(e.Yi()&&f!=null?Pi(f,n):qe(f)===qe(n))&&(a=null,f!=null&&(a=e.Oj(f,null)),a=e.Nj(n,a),a&&a.oj()),f)}function $An(e,t){var n,r,a,o,f;if(t.Ug("Path-Like Graph Wrapping",1),e.b.c.length==0){t.Vg();return}if(a=new M9e(e),f=(a.i==null&&(a.i=x7e(a,new Gj)),ze(a.i)*a.f),n=f/(a.i==null&&(a.i=x7e(a,new Gj)),ze(a.i)),a.b>n){t.Vg();return}switch(l(Q(e,(Nt(),hde)),351).g){case 2:o=new Wj;break;case 0:o=new ES;break;default:o=new Yj}if(r=o.og(e,a),!o.pg())switch(l(Q(e,EW),352).g){case 2:r=Fpt(a,r);break;case 1:r=Agt(a,r)}BLn(e,a,r),t.Vg()}function XA(e,t){var n,r,a,o,f,g,w,E;t%=24,e.q.getHours()!=t&&(r=new b.Date(e.q.getTime()),r.setDate(r.getDate()+1),g=e.q.getTimezoneOffset()-r.getTimezoneOffset(),g>0&&(w=g/60|0,E=g%60,a=e.q.getDate(),n=e.q.getHours(),n+w>=24&&++a,o=new b.Date(e.q.getFullYear(),e.q.getMonth(),a,t+w,e.q.getMinutes()+E,e.q.getSeconds(),e.q.getMilliseconds()),e.q.setTime(o.getTime()))),f=e.q.getTime(),e.q.setTime(f+36e5),e.q.getHours()!=t&&e.q.setTime(f)}function zAn(e,t){var n,r,a,o;if(ebn(e.d,e.e),e.c.a.$b(),ze(Ge(Q(t.j,(Nt(),hW))))!=0||ze(Ge(Q(t.j,hW)))!=0)for(n=y6,qe(Q(t.j,yg))!==qe((Ed(),E2))&&rt(t.j,(ft(),jb),(Hn(),!0)),o=l(Q(t.j,nM),17).a,a=0;aa&&++E,vt(f,(Sn(g+E,t.c.length),l(t.c[g+E],17))),w+=(Sn(g+E,t.c.length),l(t.c[g+E],17)).a-r,++n;n=te&&e.e[w.p]>V*e.b||Me>=n*te)&&($n(B.c,g),g=new bt,Ka(f,o),o.a.$b(),E-=C,z=b.Math.max(z,E*e.b+J),E+=Me,Te=Me,Me=0,C=0,J=0);return new ca(z,B)}function dle(e){var t,n,r,a,o,f,g;if(!e.d){if(g=new Jne,t=qM,o=t.a.zc(e,t),o==null){for(r=new or(dc(e));r.e!=r.i.gc();)n=l(gr(r),29),As(g,dle(n));t.a.Bc(e)!=null,t.a.gc()==0}for(f=g.i,a=(!e.q&&(e.q=new nt(Uf,e,11,10)),new or(e.q));a.e!=a.i.gc();++f)l(gr(a),411);As(g,(!e.q&&(e.q=new nt(Uf,e,11,10)),e.q)),Iy(g),e.d=new N5((l(Oe(tt((lb(),Vn).o),9),19),g.i),g.g),e.e=l(g.g,688),e.e==null&&(e.e=X_t),Yl(e).b&=-17}return e.d}function XE(e,t,n,r){var a,o,f,g,w,E;if(E=Wu(e.e.Dh(),t),w=0,a=l(e.g,124),Fo(),l(t,69).xk()){for(f=0;f1||V==-1)if(L=l(J,71),B=l(C,71),L.dc())B.$b();else for(f=!!Ro(t),o=0,g=e.a?L.Kc():L.Ii();g.Ob();)E=l(g.Pb(),58),a=l(B1(e,E),58),a?(f?(w=B.dd(a),w==-1?B.Gi(o,a):o!=w&&B.Ui(o,a)):B.Gi(o,a),++o):e.b&&!f&&(B.Gi(o,E),++o);else J==null?C.Wb(null):(a=B1(e,J),a==null?e.b&&!Ro(t)&&C.Wb(J):C.Wb(a))}function GAn(e,t){var n,r,a,o,f,g,w,E;for(n=new gZ,a=new hr(dr(ka(t).a.Kc(),new j));jr(a);)if(r=l(xr(a),18),!Do(r)&&(g=r.c.i,Bxe(g,SK))){if(E=tke(e,g,SK,CK),E==-1)continue;n.b=b.Math.max(n.b,E),!n.a&&(n.a=new bt),vt(n.a,g)}for(f=new hr(dr(qs(t).a.Kc(),new j));jr(f);)if(o=l(xr(f),18),!Do(o)&&(w=o.d.i,Bxe(w,CK))){if(E=tke(e,w,CK,SK),E==-1)continue;n.d=b.Math.max(n.d,E),!n.c&&(n.c=new bt),vt(n.c,w)}return n}function KAn(e,t,n,r){var a,o,f,g,w,E,C;if(n.d.i!=t.i){for(a=new op(e),x(a,(Zn(),Aa)),rt(a,(ft(),zi),n),rt(a,(Nt(),Ms),(Ra(),Mu)),$n(r.c,a),f=new gu,Mc(f,a),la(f,(Ct(),er)),g=new gu,Mc(g,a),la(g,ar),C=n.d,Fa(n,f),o=new Tw,pc(o,n),rt(o,cc,null),po(o,g),Fa(o,C),E=new Ua(n.b,0);E.b1e6)throw ue(new qz("power of ten too big"));if(e<=Ii)return sx(iP($x[1],t),t);for(r=iP($x[1],Ii),a=r,n=Zc(e-Ii),t=ua(e%Ii);iu(n,Ii)>0;)a=K5(a,r),n=Df(n,Ii);for(a=K5(a,iP($x[1],t)),a=sx(a,Ii),n=Zc(e-Ii);iu(n,Ii)>0;)a=sx(a,Ii),n=Df(n,Ii);return a=sx(a,t),a}function Ymt(e){var t,n,r,a,o,f,g,w,E,C;for(w=new G(e.a);w.aE&&r>E)C=g,E=ze(t.p[g.p])+ze(t.d[g.p])+g.o.b+g.d.a;else{a=!1,n._g()&&n.bh("bk node placement breaks on "+g+" which should have been after "+C);break}if(!a)break}return n._g()&&n.bh(t+" is feasible: "+a),a}function _ke(e,t,n,r){var a,o,f,g,w,E,C,L,B;if(o=new op(e),x(o,(Zn(),Au)),rt(o,(Nt(),Ms),(Ra(),Mu)),a=0,t){for(f=new gu,rt(f,(ft(),zi),t),rt(o,zi,t.i),la(f,(Ct(),er)),Mc(f,o),B=kd(t.e),E=B,C=0,L=E.length;C0){if(a<0&&C.a&&(a=w,o=E[0],r=0),a>=0){if(g=C.b,w==a&&(g-=r++,g==0))return 0;if(!Zvt(t,E,C,g,f)){w=a-1,E[0]=o;continue}}else if(a=-1,!Zvt(t,E,C,0,f))return 0}else{if(a=-1,co(C.c,0)==32){if(L=E[0],eht(t,E),E[0]>L)continue}else if(Ppn(t,C.c,E[0])){E[0]+=C.c.length;continue}return 0}return FDn(f,n)?E[0]:0}function ZAn(e,t,n){var r,a,o,f,g,w,E,C,L,B;for(C=new gH(new Dz(n)),g=We(ih,pg,28,e.f.e.c.length,16,1),l5e(g,g.length),n[t.a]=0,E=new G(e.f.e);E.a=0&&!r6(e,C,L);)--L;a[C]=L}for(z=0;z=0&&!r6(e,g,V);)--g;o[V]=g}for(w=0;wt[B]&&Br[w]&&FU(e,w,B,!1,!0)}function Ake(e){var t,n,r,a,o,f,g,w;n=Rt(Bt(Q(e,(b0(),K7t)))),o=e.a.c.d,g=e.a.d.d,n?(f=md(ma(new lt(g.a,g.b),o),.5),w=md(Ja(e.e),.5),t=ma(Oi(new lt(o.a,o.b),f),w),Fye(e.d,t)):(a=ze(Ge(Q(e.a,n8t))),r=e.d,o.a>=g.a?o.b>=g.b?(r.a=g.a+(o.a-g.a)/2+a,r.b=g.b+(o.b-g.b)/2-a-e.e.b):(r.a=g.a+(o.a-g.a)/2+a,r.b=o.b+(g.b-o.b)/2+a):o.b>=g.b?(r.a=o.a+(g.a-o.a)/2+a,r.b=g.b+(o.b-g.b)/2+a):(r.a=o.a+(g.a-o.a)/2+a,r.b=o.b+(g.b-o.b)/2-a-e.e.b))}function JA(e){var t,n,r,a,o,f,g,w;if(!e.f){if(w=new _I,g=new _I,t=qM,f=t.a.zc(e,t),f==null){for(o=new or(dc(e));o.e!=o.i.gc();)a=l(gr(o),29),As(w,JA(a));t.a.Bc(e)!=null,t.a.gc()==0}for(r=(!e.s&&(e.s=new nt(dl,e,21,17)),new or(e.s));r.e!=r.i.gc();)n=l(gr(r),179),De(n,102)&&qr(g,l(n,19));Iy(g),e.r=new zit(e,(l(Oe(tt((lb(),Vn).o),6),19),g.i),g.g),As(w,e.r),Iy(w),e.f=new N5((l(Oe(tt(Vn.o),5),19),w.i),w.g),Yl(e).b&=-3}return e.f}function Qmt(e){sw(e,new Xm(nw(Zv(tw(ew(new x1,nv),"ELK DisCo"),"Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out."),new z0))),gt(e,nv,_he,It(X_e)),gt(e,nv,Ahe,It(W0e)),gt(e,nv,Ox,It(I7t)),gt(e,nv,Xw,It(Y_e)),gt(e,nv,bEe,It(B7t)),gt(e,nv,mEe,It(P7t)),gt(e,nv,pEe,It(F7t)),gt(e,nv,vEe,It(N7t)),gt(e,nv,CEe,It(O7t)),gt(e,nv,SEe,It(K0e)),gt(e,nv,_Ee,It(W_e)),gt(e,nv,AEe,It(vK))}function zU(){zU=U,bPe=he(le(kf,1),Ad,28,15,[48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70]),S_t=new RegExp(`[ +\r\f]+`);try{jM=he(le(POn,1),Rn,2114,0,[new KI((iye(),KV("yyyy-MM-dd'T'HH:mm:ss'.'SSSZ",MO((zz(),zz(),NL))))),new KI(KV("yyyy-MM-dd'T'HH:mm:ss'.'SSS",MO(NL))),new KI(KV("yyyy-MM-dd'T'HH:mm:ss",MO(NL))),new KI(KV("yyyy-MM-dd'T'HH:mm",MO(NL))),new KI(KV("yyyy-MM-dd",MO(NL)))])}catch(e){if(e=bs(e),!De(e,82))throw ue(e)}}function tLn(e,t){var n,r,a,o;if(a=Jl(e.d,1)!=0,r=cke(e,t),r==0&&Rt(Bt(Q(t.j,(ft(),jb)))))return 0;!Rt(Bt(Q(t.j,(ft(),jb))))&&!Rt(Bt(Q(t.j,j6)))||qe(Q(t.j,(Nt(),yg)))===qe((Ed(),E2))?t.c.mg(t.e,a):a=Rt(Bt(Q(t.j,jb))),cP(e,t,a,!0),Rt(Bt(Q(t.j,j6)))&&rt(t.j,j6,(Hn(),!1)),Rt(Bt(Q(t.j,jb)))&&(rt(t.j,jb,(Hn(),!1)),rt(t.j,j6,!0)),n=cke(e,t);do{if(w7e(e),n==0)return 0;a=!a,o=n,cP(e,t,a,!1),n=cke(e,t)}while(o>n);return o}function Jmt(e,t){var n,r,a,o;if(a=Jl(e.d,1)!=0,r=xU(e,t),r==0&&Rt(Bt(Q(t.j,(ft(),jb)))))return 0;!Rt(Bt(Q(t.j,(ft(),jb))))&&!Rt(Bt(Q(t.j,j6)))||qe(Q(t.j,(Nt(),yg)))===qe((Ed(),E2))?t.c.mg(t.e,a):a=Rt(Bt(Q(t.j,jb))),cP(e,t,a,!0),Rt(Bt(Q(t.j,j6)))&&rt(t.j,j6,(Hn(),!1)),Rt(Bt(Q(t.j,jb)))&&(rt(t.j,jb,(Hn(),!1)),rt(t.j,j6,!0)),n=xU(e,t);do{if(w7e(e),n==0)return 0;a=!a,o=n,cP(e,t,a,!1),n=xU(e,t)}while(o>n);return o}function Lke(e,t,n,r){var a,o,f,g,w,E,C,L,B;return w=ma(new lt(n.a,n.b),e),E=w.a*t.b-w.b*t.a,C=t.a*r.b-t.b*r.a,L=(w.a*r.b-w.b*r.a)/C,B=E/C,C==0?E==0?(a=Oi(new lt(n.a,n.b),md(new lt(r.a,r.b),.5)),o=pb(e,a),f=pb(Oi(new lt(e.a,e.b),t),a),g=b.Math.sqrt(r.a*r.a+r.b*r.b)*.5,o=0&&L<=1&&B>=0&&B<=1?Oi(new lt(e.a,e.b),md(new lt(t.a,t.b),L)):null}function nLn(e,t,n){var r,a,o,f,g;if(r=l(Q(e,(Nt(),J1e)),21),n.a>t.a&&(r.Hc((Ym(),EM))?e.c.a+=(n.a-t.a)/2:r.Hc(TM)&&(e.c.a+=n.a-t.a)),n.b>t.b&&(r.Hc((Ym(),SM))?e.c.b+=(n.b-t.b)/2:r.Hc(CM)&&(e.c.b+=n.b-t.b)),l(Q(e,(ft(),Lu)),21).Hc((Ho(),vf))&&(n.a>t.a||n.b>t.b))for(g=new G(e.a);g.at.a&&(r.Hc((Ym(),EM))?e.c.a+=(n.a-t.a)/2:r.Hc(TM)&&(e.c.a+=n.a-t.a)),n.b>t.b&&(r.Hc((Ym(),SM))?e.c.b+=(n.b-t.b)/2:r.Hc(CM)&&(e.c.b+=n.b-t.b)),l(Q(e,(ft(),Lu)),21).Hc((Ho(),vf))&&(n.a>t.a||n.b>t.b))for(f=new G(e.a);f.a0?e.i:0)>t&&w>0&&(o=0,f+=w+e.i,a=b.Math.max(a,B),r+=w+e.i,w=0,B=0,n&&(++L,vt(e.n,new PH(e.s,f,e.i))),g=0),B+=E.g+(g>0?e.i:0),w=b.Math.max(w,E.f),n&&exe(l(jt(e.n,L),209),E),o+=E.g+(g>0?e.i:0),++g;return a=b.Math.max(a,B),r+=w,n&&(e.r=a,e.d=r,ixe(e.j)),new ef(e.s,e.t,a,r)}function gle(e){var t,n,r,a,o,f,g,w,E,C,L,B;for(e.b=!1,L=gs,w=ia,B=gs,E=ia,r=e.e.a.ec().Kc();r.Ob();)for(n=l(r.Pb(),272),a=n.a,L=b.Math.min(L,a.c),w=b.Math.max(w,a.c+a.b),B=b.Math.min(B,a.d),E=b.Math.max(E,a.d+a.a),f=new G(n.c);f.ae.o.a&&(C=(w-e.o.a)/2,g.b=b.Math.max(g.b,C),g.c=b.Math.max(g.c,C))}}function aLn(e){var t,n,r,a,o,f,g,w;for(o=new Kot,Fln(o,(hx(),dSt)),r=(a=ace(e,We(zt,dt,2,0,6,1)),new kr(new Il(new ase(e,a).b)));r.bg?1:-1:W7e(e.a,t.a,o),a==-1)L=-w,C=f==w?Doe(t.a,g,e.a,o):Ooe(t.a,g,e.a,o);else if(L=f,f==w){if(a==0)return Cd(),BL;C=Doe(e.a,o,t.a,g)}else C=Ooe(e.a,o,t.a,g);return E=new Im(L,C.length,C),iA(E),E}function oLn(e,t){var n,r,a,o;if(o=Pmt(t),!t.c&&(t.c=new nt(Hl,t,9,9)),Is(new bn(null,(!t.c&&(t.c=new nt(Hl,t,9,9)),new kn(t.c,16))),new $We(o)),a=l(Q(o,(ft(),Lu)),21),ZMn(t,a),a.Hc((Ho(),vf)))for(r=new or((!t.c&&(t.c=new nt(Hl,t,9,9)),t.c));r.e!=r.i.gc();)n=l(gr(r),123),ADn(e,t,o,n);return l(at(t,(Nt(),bv)),181).gc()!=0&&_bt(t,o),Rt(Bt(Q(o,XMe)))&&a.Fc(nW),ns(o,CB)&&NJe(new D8e(ze(Ge(Q(o,CB)))),o),qe(at(t,p4))===qe((rp(),A2))?JIn(e,t,o):BIn(e,t,o),o}function cLn(e){var t,n,r,a,o,f,g,w;for(a=new G(e.b);a.a0?tf(n.a,0,o-1):""):(Ga(0,o-1,e.length),e.substr(0,o-1)):n?n.a:e}function uLn(e,t){var n,r,a,o,f,g,w;for(t.Ug("Sort By Input Model "+Q(e,(Nt(),yg)),1),a=0,r=new G(e.b);r.a=e.b.length?(o[a++]=f.b[r++],o[a++]=f.b[r++]):r>=f.b.length?(o[a++]=e.b[n++],o[a++]=e.b[n++]):f.b[r]0?e.i:0)),++t;for(g8e(e.n,w),e.d=n,e.r=r,e.g=0,e.f=0,e.e=0,e.o=gs,e.p=gs,o=new G(e.b);o.a0&&(a=(!e.n&&(e.n=new nt(ec,e,1,7)),l(Oe(e.n,0),135)).a,!a||hi(hi((t.a+=' "',t),a),'"'))),n=(!e.b&&(e.b=new Ln(_r,e,4,7)),!(e.b.i<=1&&(!e.c&&(e.c=new Ln(_r,e,5,8)),e.c.i<=1))),n?t.a+=" [":t.a+=" ",hi(t,Eye(new Zie,new or(e.b))),n&&(t.a+="]"),t.a+=Phe,n&&(t.a+="["),hi(t,Eye(new Zie,new or(e.c))),n&&(t.a+="]"),t.a)}function hLn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn;for(Ze=e.c,ot=t.c,n=gc(Ze.a,e,0),r=gc(ot.a,t,0),Me=l(Rw(e,(qo(),$l)).Kc().Pb(),12),an=l(Rw(e,zu).Kc().Pb(),12),$e=l(Rw(t,$l).Kc().Pb(),12),Bn=l(Rw(t,zu).Kc().Pb(),12),fe=kd(Me.e),St=kd(an.g),Te=kd($e.e),cn=kd(Bn.g),Fy(e,r,ot),f=Te,C=0,V=f.length;CC?new Pm((J0(),E4),n,t,E-C):E>0&&C>0&&(new Pm((J0(),E4),t,n,0),new Pm(E4,n,t,0))),f)}function gLn(e,t,n){var r,a,o;for(e.a=new bt,o=Rr(t.b,0);o.b!=o.d.c;){for(a=l(Br(o),40);l(Q(a,(Hc(),$d)),17).a>e.a.c.length-1;)vt(e.a,new ca(y6,hCe));r=l(Q(a,$d),17).a,n==(Js(),uc)||n==vc?(a.e.aze(Ge(l(jt(e.a,r),42).b))&&ct(l(jt(e.a,r),42),a.e.a+a.f.a)):(a.e.bze(Ge(l(jt(e.a,r),42).b))&&ct(l(jt(e.a,r),42),a.e.b+a.f.b))}}function tvt(e,t,n,r){var a,o,f,g,w,E,C;if(o=zV(r),g=Rt(Bt(Q(r,(Nt(),VMe)))),(g||Rt(Bt(Q(e,bW))))&&!P5(l(Q(e,Ms),101)))a=gx(o),w=vke(e,n,n==(qo(),zu)?a:BN(a));else switch(w=new gu,Mc(w,e),t?(C=w.n,C.a=t.a-e.n.a,C.b=t.b-e.n.b,opt(C,0,0,e.o.a,e.o.b),la(w,kmt(w,o))):(a=gx(o),la(w,n==(qo(),zu)?a:BN(a))),f=l(Q(r,(ft(),Lu)),21),E=w.j,o.g){case 2:case 1:(E==(Ct(),Qn)||E==Dr)&&f.Fc((Ho(),B6));break;case 4:case 3:(E==(Ct(),ar)||E==er)&&f.Fc((Ho(),B6))}return w}function nvt(e,t){var n,r,a,o,f,g;for(f=new qm(new Sr(e.f.b).a);f.b;){if(o=Nw(f),a=l(o.ld(),602),t==1){if(a.Af()!=(Js(),wf)&&a.Af()!=Q1)continue}else if(a.Af()!=(Js(),uc)&&a.Af()!=vc)continue;switch(r=l(l(o.md(),42).b,86),g=l(l(o.md(),42).a,194),n=g.c,a.Af().g){case 2:r.g.c=e.e.a,r.g.b=b.Math.max(1,r.g.b+n);break;case 1:r.g.c=r.g.c+n,r.g.b=b.Math.max(1,r.g.b-n);break;case 4:r.g.d=e.e.b,r.g.a=b.Math.max(1,r.g.a+n);break;case 3:r.g.d=r.g.d+n,r.g.a=b.Math.max(1,r.g.a-n)}}}function pLn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J;for(g=We(Vr,di,28,t.b.c.length,15,1),E=We(l1e,it,273,t.b.c.length,0,1),w=We(wg,m2,10,t.b.c.length,0,1),L=e.a,B=0,z=L.length;B0&&w[r]&&(V=j5(e.b,w[r],a)),J=b.Math.max(J,a.c.c.b+V);for(o=new G(C.e);o.a1)throw ue(new Yn(ZP));w||(o=sg(t,r.Kc().Pb()),f.Fc(o))}return N7e(e,t9e(e,t,n),f)}function HU(e,t,n){var r,a,o,f,g,w,E,C;if(up(e.e,t))w=(Fo(),l(t,69).xk()?new nH(t,e):new yO(t,e)),EU(w.c,w.b),F_(w,l(n,16));else{for(C=Wu(e.e.Dh(),t),r=l(e.g,124),f=0;f"}w!=null&&(t.a+=""+w)}else e.e?(g=e.e.zb,g!=null&&(t.a+=""+g)):(t.a+="?",e.b?(t.a+=" super ",wle(e.b,t)):e.f&&(t.a+=" extends ",wle(e.f,t)))}function xLn(e){e.b=null,e.a=null,e.o=null,e.q=null,e.v=null,e.w=null,e.B=null,e.p=null,e.Q=null,e.R=null,e.S=null,e.T=null,e.U=null,e.V=null,e.W=null,e.bb=null,e.eb=null,e.ab=null,e.H=null,e.db=null,e.c=null,e.d=null,e.f=null,e.n=null,e.r=null,e.s=null,e.u=null,e.G=null,e.J=null,e.e=null,e.j=null,e.i=null,e.g=null,e.k=null,e.t=null,e.F=null,e.I=null,e.L=null,e.M=null,e.O=null,e.P=null,e.$=null,e.N=null,e.Z=null,e.cb=null,e.K=null,e.D=null,e.A=null,e.C=null,e._=null,e.fb=null,e.X=null,e.Y=null,e.gb=!1,e.hb=!1}function kLn(e){var t,n,r,a;if(r=Dle((!e.c&&(e.c=XO(Zc(e.f))),e.c),0),e.e==0||e.a==0&&e.f!=-1&&e.e<0)return r;if(t=y7e(e)<0?1:0,n=e.e,a=(r.length+1+b.Math.abs(ua(e.e)),new S5),t==1&&(a.a+="-"),e.e>0)if(n-=r.length-t,n>=0){for(a.a+="0.";n>lv.length;n-=lv.length)Qit(a,lv);Prt(a,lv,ua(n)),hi(a,(Xn(t,r.length+1),r.substr(t)))}else n=t-n,hi(a,tf(r,t,ua(n))),a.a+=".",hi(a,w5e(r,ua(n)));else{for(hi(a,(Xn(t,r.length+1),r.substr(t)));n<-lv.length;n+=lv.length)Qit(a,lv);Prt(a,lv,ua(-n))}return a.a}function yle(e){var t,n,r,a,o,f,g,w,E;return!(e.k!=(Zn(),Ps)||e.j.c.length<=1||(o=l(Q(e,(Nt(),Ms)),101),o==(Ra(),Mu))||(a=(By(),(e.q?e.q:(Cn(),Cn(),mg))._b(g3)?r=l(Q(e,g3),203):r=l(Q(eo(e),eM),203),r),a==_W)||!(a==G6||a==U6)&&(f=ze(Ge(Py(e,tM))),t=l(Q(e,_B),140),!t&&(t=new n4e(f,f,f,f)),E=Oc(e,(Ct(),er)),w=t.d+t.a+(E.gc()-1)*f,w>e.o.b||(n=Oc(e,ar),g=t.d+t.a+(n.gc()-1)*f,g>e.o.b)))}function ELn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te;t.Ug("Orthogonal edge routing",1),E=ze(Ge(Q(e,(Nt(),V6)))),n=ze(Ge(Q(e,q6))),r=ze(Ge(Q(e,vv))),B=new Hae(0,n),te=0,f=new Ua(e.b,0),g=null,C=null,w=null,L=null;do C=f.b0?(z=(V-1)*n,g&&(z+=r),C&&(z+=r),zt||Rt(Bt(at(w,(z1(),$B)))))&&(a=0,o+=C.b+n,$n(L.c,C),C=new Q5e(o,n),r=new kce(0,C.f,C,n),bV(C,r),a=0),r.b.c.length==0||!Rt(Bt(at(ds(w),(z1(),hge))))&&(w.f>=r.o&&w.f<=r.f||r.a*.5<=w.f&&r.a*1.5>=w.f)?y8e(r,w):(f=new kce(r.s+r.r+n,C.f,C,n),bV(C,f),y8e(f,w)),a=w.i+w.g;return $n(L.c,C),L}function eL(e){var t,n,r,a;if(!(e.b==null||e.b.length<=2)&&!e.a){for(t=0,a=0;a=e.b[a+1])a+=2;else if(n0)for(r=new Ol(l($i(e.a,o),21)),Cn(),Vs(r,new GI(t)),a=new Ua(o.b,0);a.b0&&r>=-6?r>=0?EO(o,n-ua(e.e),String.fromCharCode(46)):(hce(o,t-1,t-1,"0."),EO(o,t+1,If(lv,0,-ua(r)-1))):(n-t>=1&&(EO(o,t,String.fromCharCode(46)),++n),EO(o,n,String.fromCharCode(69)),r>0&&EO(o,++n,String.fromCharCode(43)),EO(o,++n,""+Y_(Zc(r)))),e.g=o.a,e.g))}function OLn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St;r=ze(Ge(Q(t,(Nt(),KMe)))),Ze=l(Q(t,nM),17).a,B=4,a=3,ot=20/Ze,z=!1,w=0,f=Ii;do{for(o=w!=1,L=w!=0,St=0,te=e.a,Te=0,$e=te.length;Te<$e;++Te)V=te[Te],V.f=null,yDn(e,V,o,L,r),St+=b.Math.abs(V.a);do g=oAn(e,t);while(g);for(J=e.a,fe=0,Me=J.length;feZe)?(w=2,f=Ii):w==0?(w=1,f=St):(w=0,f=St)):(z=St>=f||f-St0?1:uw(isNaN(r),isNaN(0)))>=0^(f0(Nd),(b.Math.abs(g)<=Nd||g==0||isNaN(g)&&isNaN(0)?0:g<0?-1:g>0?1:uw(isNaN(g),isNaN(0)))>=0)?b.Math.max(g,r):(f0(Nd),(b.Math.abs(r)<=Nd||r==0||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:uw(isNaN(r),isNaN(0)))>0?b.Math.sqrt(g*g+r*r):-b.Math.sqrt(g*g+r*r))}function Qm(e,t){var n,r,a,o,f,g;if(t){if(!e.a&&(e.a=new jz),e.e==2){Rz(e.a,t);return}if(t.e==1){for(a=0;a=Io?Xo(n,w8e(r)):Uk(n,r&Zs),f=new coe(10,null,0),mgn(e.a,f,g-1)):(n=(f.Mm().length+o,new h_),Xo(n,f.Mm())),t.e==0?(r=t.Km(),r>=Io?Xo(n,w8e(r)):Uk(n,r&Zs)):Xo(n,t.Mm()),l(f,530).b=n.a}}function BLn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te;if(!n.dc()){for(g=0,B=0,r=n.Kc(),V=l(r.Pb(),17).a;g1&&(w=E.Hg(w,e.a,g));return w.c.length==1?l(jt(w,w.c.length-1),238):w.c.length==2?CLn((Sn(0,w.c.length),l(w.c[0],238)),(Sn(1,w.c.length),l(w.c[1],238)),f,o):null}function $Ln(e,t,n){var r,a,o,f,g,w,E;for(n.Ug("Find roots",1),e.a.c.length=0,a=Rr(t.b,0);a.b!=a.d.c;)r=l(Br(a),40),r.b.b==0&&(rt(r,(Qi(),Vb),(Hn(),!0)),vt(e.a,r));switch(e.a.c.length){case 0:o=new xce(0,t,"DUMMY_ROOT"),rt(o,(Qi(),Vb),(Hn(),!0)),rt(o,Nde,!0),ui(t.b,o);break;case 1:break;default:for(f=new xce(0,t,DG),w=new G(e.a);w.a=b.Math.abs(r.b)?(r.b=0,o.d+o.a>f.d&&o.df.c&&o.c0){if(t=new eye(e.i,e.g),n=e.i,o=n<100?null:new nb(n),e.Tj())for(r=0;r0){for(g=e.g,E=e.i,uA(e),o=E<100?null:new nb(E),r=0;r>13|(e.m&15)<<9,a=e.m>>4&8191,o=e.m>>17|(e.h&255)<<5,f=(e.h&1048320)>>8,g=t.l&8191,w=t.l>>13|(t.m&15)<<9,E=t.m>>4&8191,C=t.m>>17|(t.h&255)<<5,L=(t.h&1048320)>>8,cn=n*g,an=r*g,Bn=a*g,jn=o*g,ur=f*g,w!=0&&(an+=n*w,Bn+=r*w,jn+=a*w,ur+=o*w),E!=0&&(Bn+=n*E,jn+=r*E,ur+=a*E),C!=0&&(jn+=n*C,ur+=r*C),L!=0&&(ur+=n*L),z=cn&eh,V=(an&511)<<13,B=z+V,te=cn>>22,fe=an>>9,Te=(Bn&262143)<<4,Me=(jn&31)<<17,J=te+fe+Te+Me,Ze=Bn>>18,ot=jn>>5,St=(ur&4095)<<8,$e=Ze+ot+St,J+=B>>22,B&=eh,$e+=J>>22,J&=eh,$e&=hp,qu(B,J,$e)}function dvt(e){var t,n,r,a,o,f,g;if(g=l(jt(e.j,0),12),g.g.c.length!=0&&g.e.c.length!=0)throw ue(new nc("Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges."));if(g.g.c.length!=0){for(o=gs,n=new G(g.g);n.a4)if(e.fk(t)){if(e.al()){if(a=l(t,54),r=a.Eh(),w=r==e.e&&(e.ml()?a.yh(a.Fh(),e.il())==e.jl():-1-a.Fh()==e.Lj()),e.nl()&&!w&&!r&&a.Jh()){for(o=0;o0&&gpt(e,g,L);for(a=new G(L);a.ae.d[f.p]&&(n+=f6e(e.b,o)*l(w.b,17).a,gb(e.a,pt(o)));for(;!l_(e.a);)U6e(e.b,l(X8(e.a),17).a)}return n}function ULn(e,t){var n,r,a,o,f,g,w,E,C,L;if(C=l(Q(e,(ft(),Wc)),64),r=l(jt(e.j,0),12),C==(Ct(),Qn)?la(r,Dr):C==Dr&&la(r,Qn),l(Q(t,(Nt(),bv)),181).Hc((mh(),Cv))){if(w=ze(Ge(Q(e,GT))),E=ze(Ge(Q(e,KT))),f=ze(Ge(Q(e,y4))),g=l(Q(t,v4),21),g.Hc((Rl(),vp)))for(n=E,L=e.o.a/2-r.n.a,o=new G(r.f);o.a0&&(E=e.n.a/o);break;case 2:case 4:a=e.i.o.b,a>0&&(E=e.n.b/a)}rt(e,(ft(),l3),E)}if(w=e.o,f=e.a,r)f.a=r.a,f.b=r.b,e.d=!0;else if(t!=Z1&&t!=Wb&&g!=Pc)switch(g.g){case 1:f.a=w.a/2;break;case 2:f.a=w.a,f.b=w.b/2;break;case 3:f.a=w.a/2,f.b=w.b;break;case 4:f.b=w.b/2}else f.a=w.a/2,f.b=w.b/2}function tL(e){var t,n,r,a,o,f,g,w,E,C;if(e.Pj())if(C=e.Ej(),w=e.Qj(),C>0)if(t=new T7e(e.pj()),n=C,o=n<100?null:new nb(n),AO(e,n,t.g),a=n==1?e.Ij(4,Oe(t,0),null,0,w):e.Ij(6,t,null,-1,w),e.Mj()){for(r=new or(t);r.e!=r.i.gc();)o=e.Oj(gr(r),o);o?(o.nj(a),o.oj()):e.Jj(a)}else o?(o.nj(a),o.oj()):e.Jj(a);else AO(e,e.Ej(),e.Fj()),e.Jj(e.Ij(6,(Cn(),_o),null,-1,w));else if(e.Mj())if(C=e.Ej(),C>0){for(g=e.Fj(),E=C,AO(e,C,g),o=E<100?null:new nb(E),r=0;r1&&wl(f)*gh(f)/2>g[0]){for(o=0;og[o];)++o;V=new Zp(J,0,o+1),L=new hV(V),C=wl(f)/gh(f),w=Lle(L,t,new A8,n,r,a,C),Oi(Y0(L.e),w),K8($E(B,L),aT),z=new Zp(J,o+1,J.c.length),cxe(B,z),J.c.length=0,E=0,gst(g,g.length,0)}else te=B.b.c.length==0?null:jt(B.b,0),te!=null&&rce(B,0),E>0&&(g[E]=g[E-1]),g[E]+=wl(f)*gh(f),++E,$n(J.c,f);return J}function QLn(e,t){var n,r,a,o;n=t.b,o=new Ol(n.j),a=0,r=n.j,r.c.length=0,mw(l(zm(e.b,(Ct(),Qn),(Ow(),o3)),15),n),a=zN(o,a,new Gv,r),mw(l(zm(e.b,Qn,Rb),15),n),a=zN(o,a,new bee,r),mw(l(zm(e.b,Qn,a3),15),n),mw(l(zm(e.b,ar,o3),15),n),mw(l(zm(e.b,ar,Rb),15),n),a=zN(o,a,new $j,r),mw(l(zm(e.b,ar,a3),15),n),mw(l(zm(e.b,Dr,o3),15),n),a=zN(o,a,new zj,r),mw(l(zm(e.b,Dr,Rb),15),n),a=zN(o,a,new qj,r),mw(l(zm(e.b,Dr,a3),15),n),mw(l(zm(e.b,er,o3),15),n),a=zN(o,a,new Bj,r),mw(l(zm(e.b,er,Rb),15),n),mw(l(zm(e.b,er,a3),15),n)}function JLn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z;for(g=new G(t);g.a.5?fe-=f*2*(V-.5):V<.5&&(fe+=o*2*(.5-V)),a=g.d.b,fete.a-J-C&&(fe=te.a-J-C),g.n.a=t+fe}}function nMn(e){var t,n,r,a,o;if(r=l(Q(e,(Nt(),Qu)),171),r==(hf(),$b)){for(n=new hr(dr(ka(e).a.Kc(),new j));jr(n);)if(t=l(xr(n),18),!Aut(t))throw ue(new Vp(jhe+HN(e)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. FIRST_SEPARATE nodes must not have incoming edges."))}else if(r==d4){for(o=new hr(dr(qs(e).a.Kc(),new j));jr(o);)if(a=l(xr(o),18),!Aut(a))throw ue(new Vp(jhe+HN(e)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. LAST_SEPARATE nodes must not have outgoing edges."))}}function bP(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V;if(e.e&&e.c.c>19&&(t=xE(t),w=!w),f=$Tn(t),o=!1,a=!1,r=!1,e.h==SP&&e.m==0&&e.l==0)if(a=!0,o=!0,f==-1)e=ent((iE(),WSe)),r=!0,w=!w;else return g=D9e(e,f),w&&yce(g),n&&(Nb=qu(0,0,0)),g;else e.h>>19&&(o=!0,e=xE(e),r=!0,w=!w);return f!=-1?pyn(e,f,w,o,n):bxe(e,t)<0?(n&&(o?Nb=xE(e):Nb=qu(e.l,e.m,e.h)),qu(0,0,0)):R_n(r?e:qu(e.l,e.m,e.h),t,w,o,a,n)}function Tle(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V;if(f=e.e,w=t.e,f==0)return t;if(w==0)return e;if(o=e.d,g=t.d,o+g==2)return n=va(e.a[0],Vo),r=va(t.a[0],Vo),f==w?(C=bo(n,r),V=Yr(C),z=Yr(ub(C,32)),z==0?new Qg(f,V):new Im(f,2,he(le(Vr,1),di,28,15,[V,z]))):(Cd(),Aq(f<0?Df(r,n):Df(n,r),0)?kb(f<0?Df(r,n):Df(n,r)):J_(kb(r2(f<0?Df(r,n):Df(n,r)))));if(f==w)B=f,L=o>=g?Ooe(e.a,o,t.a,g):Ooe(t.a,g,e.a,o);else{if(a=o!=g?o>g?1:-1:W7e(e.a,t.a,o),a==0)return Cd(),BL;a==1?(B=f,L=Doe(e.a,o,t.a,g)):(B=w,L=Doe(t.a,g,e.a,o))}return E=new Im(B,L.length,L),iA(E),E}function iMn(e,t){var n,r,a,o,f,g,w;if(!(e.g>t.f||t.g>e.f)){for(n=0,r=0,f=e.w.a.ec().Kc();f.Ob();)a=l(f.Pb(),12),Ice(Ic(he(le(Ea,1),dt,8,0,[a.i.n,a.n,a.a])).b,t.g,t.f)&&++n;for(g=e.r.a.ec().Kc();g.Ob();)a=l(g.Pb(),12),Ice(Ic(he(le(Ea,1),dt,8,0,[a.i.n,a.n,a.a])).b,t.g,t.f)&&--n;for(w=t.w.a.ec().Kc();w.Ob();)a=l(w.Pb(),12),Ice(Ic(he(le(Ea,1),dt,8,0,[a.i.n,a.n,a.a])).b,e.g,e.f)&&++r;for(o=t.r.a.ec().Kc();o.Ob();)a=l(o.Pb(),12),Ice(Ic(he(le(Ea,1),dt,8,0,[a.i.n,a.n,a.a])).b,e.g,e.f)&&--r;n=0)return n;switch(kw(ic(e,n))){case 2:{if(vn("",o2(e,n.qk()).xe())){if(w=HO(ic(e,n)),g=Wk(ic(e,n)),C=P9e(e,t,w,g),C)return C;for(a=hke(e,t),f=0,L=a.gc();f1)throw ue(new Yn(ZP));for(C=Wu(e.e.Dh(),t),r=l(e.g,124),f=0;f1,E=new N1(B.b);Lc(E.a)||Lc(E.b);)w=l(Lc(E.a)?re(E.a):re(E.b),18),L=w.c==B?w.d:w.c,b.Math.abs(Ic(he(le(Ea,1),dt,8,0,[L.i.n,L.n,L.a])).b-f.b)>1&&UCn(e,w,f,o,B)}}function lMn(e){var t,n,r,a,o,f;if(a=new Ua(e.e,0),r=new Ua(e.a,0),e.d)for(n=0;nwfe;){for(o=t,f=0;b.Math.abs(t-o)0),a.a.Xb(a.c=--a.b),CAn(e,e.b-f,o,r,a),mr(a.b0),r.a.Xb(r.c=--r.b)}if(!e.d)for(n=0;n0?(e.f[C.p]=z/(C.e.c.length+C.g.c.length),e.c=b.Math.min(e.c,e.f[C.p]),e.b=b.Math.max(e.b,e.f[C.p])):g&&(e.f[C.p]=z)}}function fMn(e){e.b=null,e.bb=null,e.fb=null,e.qb=null,e.a=null,e.c=null,e.d=null,e.e=null,e.f=null,e.n=null,e.M=null,e.L=null,e.Q=null,e.R=null,e.K=null,e.db=null,e.eb=null,e.g=null,e.i=null,e.j=null,e.k=null,e.gb=null,e.o=null,e.p=null,e.q=null,e.r=null,e.$=null,e.ib=null,e.S=null,e.T=null,e.t=null,e.s=null,e.u=null,e.v=null,e.w=null,e.B=null,e.A=null,e.C=null,e.D=null,e.F=null,e.G=null,e.H=null,e.I=null,e.J=null,e.P=null,e.Z=null,e.U=null,e.V=null,e.W=null,e.X=null,e.Y=null,e._=null,e.ab=null,e.cb=null,e.hb=null,e.nb=null,e.lb=null,e.mb=null,e.ob=null,e.pb=null,e.jb=null,e.kb=null,e.N=!1,e.O=!1}function dMn(e,t,n){var r,a,o,f;for(n.Ug("Graph transformation ("+e.a+")",1),f=_w(t.a),o=new G(t.b);o.a=g.b.c)&&(g.b=t),(!g.c||t.c<=g.c.c)&&(g.d=g.c,g.c=t),(!g.e||t.d>=g.e.d)&&(g.e=t),(!g.f||t.d<=g.f.d)&&(g.f=t);return r=new nU((wE(),s3)),QO(e,M8t,new Il(he(le(fB,1),Rn,382,0,[r]))),f=new nU(o4),QO(e,L8t,new Il(he(le(fB,1),Rn,382,0,[f]))),a=new nU(a4),QO(e,A8t,new Il(he(le(fB,1),Rn,382,0,[a]))),o=new nU(M6),QO(e,_8t,new Il(he(le(fB,1),Rn,382,0,[o]))),Yue(r.c,s3),Yue(a.c,a4),Yue(o.c,M6),Yue(f.c,o4),g.a.c.length=0,ra(g.a,r.c),ra(g.a,lf(a.c)),ra(g.a,o.c),ra(g.a,lf(f.c)),g}function bMn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V;for(t.Ug(Ayt,1),z=ze(Ge(at(e,(ug(),T4)))),f=ze(Ge(at(e,(z1(),wM)))),g=l(at(e,vM),107),v7e((!e.a&&(e.a=new nt(Ai,e,10,11)),e.a)),C=uvt((!e.a&&(e.a=new nt(Ai,e,10,11)),e.a),z,f),!e.a&&(e.a=new nt(Ai,e,10,11)),E=new G(C);E.a0&&(e.a=w+(z-1)*o,t.c.b+=e.a,t.f.b+=e.a)),V.a.gc()!=0&&(B=new Hae(1,o),z=Rke(B,t,V,J,t.f.b+w-t.c.b),z>0&&(t.f.b+=w+(z-1)*o))}function bvt(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e;for(C=ze(Ge(Q(e,(Nt(),b3)))),r=ze(Ge(Q(e,rDe))),B=new EI,rt(B,b3,C+r),E=t,fe=E.d,J=E.c.i,Te=E.d.i,te=oye(J.c),Me=oye(Te.c),a=new bt,L=te;L<=Me;L++)g=new op(e),x(g,(Zn(),Aa)),rt(g,(ft(),zi),E),rt(g,Ms,(Ra(),Mu)),rt(g,kW,B),z=l(jt(e.b,L),30),L==te?Fy(g,z.a.c.length-n,z):Va(g,z),$e=ze(Ge(Q(E,x2))),$e<0&&($e=0,rt(E,x2,$e)),g.o.b=$e,V=b.Math.floor($e/2),f=new gu,la(f,(Ct(),er)),Mc(f,g),f.n.b=V,w=new gu,la(w,ar),Mc(w,g),w.n.b=V,Fa(E,f),o=new Tw,pc(o,E),rt(o,cc,null),po(o,w),Fa(o,fe),s8n(g,E,o),$n(a.c,o),E=o;return a}function Cle(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me;for(w=l(d2(e,(Ct(),er)).Kc().Pb(),12).e,z=l(d2(e,ar).Kc().Pb(),12).g,g=w.c.length,Me=I1(l(jt(e.j,0),12));g-- >0;){for(J=(Sn(0,w.c.length),l(w.c[0],18)),a=(Sn(0,z.c.length),l(z.c[0],18)),Te=a.d.e,o=gc(Te,a,0),$bn(J,a.d,o),po(a,null),Fa(a,null),V=J.a,t&&ui(V,new Eo(Me)),r=Rr(a.a,0);r.b!=r.d.c;)n=l(Br(r),8),ui(V,new Eo(n));for(fe=J.b,B=new G(a.b);B.af)&&na(e.b,l(te.b,18));++g}o=f}}}function Pke(e,t){var n;if(t==null||vn(t,ul)||t.length==0&&e.k!=(g2(),t9))return null;switch(e.k.g){case 1:return QV(t,wT)?(Hn(),ST):QV(t,Ffe)?(Hn(),Pb):null;case 2:try{return pt(Oh(t,lo,Ii))}catch(r){if(r=bs(r),De(r,130))return null;throw ue(r)}case 4:try{return jy(t)}catch(r){if(r=bs(r),De(r,130))return null;throw ue(r)}case 3:return t;case 5:return F0t(e),Xpt(e,t);case 6:return F0t(e),mTn(e,e.a,t);case 7:try{return n=AEn(e),n.cg(t),n}catch(r){if(r=bs(r),De(r,33))return null;throw ue(r)}default:throw ue(new nc("Invalid type set for this layout option."))}}function Bke(e){var t;switch(e.d){case 1:{if(e.Sj())return e.o!=-2;break}case 2:{if(e.Sj())return e.o==-2;break}case 3:case 5:case 4:case 6:case 7:return e.o>-2;default:return!1}switch(t=e.Rj(),e.p){case 0:return t!=null&&Rt(Bt(t))!=I_(e.k,0);case 1:return t!=null&&l(t,222).a!=Yr(e.k)<<24>>24;case 2:return t!=null&&l(t,180).a!=(Yr(e.k)&Zs);case 6:return t!=null&&I_(l(t,168).a,e.k);case 5:return t!=null&&l(t,17).a!=Yr(e.k);case 7:return t!=null&&l(t,191).a!=Yr(e.k)<<16>>16;case 3:return t!=null&&ze(Ge(t))!=e.j;case 4:return t!=null&&l(t,161).a!=e.j;default:return t==null?e.n!=null:!Pi(t,e.n)}}function mP(e,t,n){var r,a,o,f;return e.ol()&&e.nl()&&(f=Fae(e,l(n,58)),qe(f)!==qe(n))?(e.xj(t),e.Dj(t,ylt(e,t,f)),e.al()&&(o=(a=l(n,54),e.ml()?e.kl()?a.Th(e.b,Ro(l(Mn(sl(e.b),e.Lj()),19)).n,l(Mn(sl(e.b),e.Lj()).Hk(),29).kk(),null):a.Th(e.b,ms(a.Dh(),Ro(l(Mn(sl(e.b),e.Lj()),19))),null,null):a.Th(e.b,-1-e.Lj(),null,null)),!l(f,54).Ph()&&(o=(r=l(f,54),e.ml()?e.kl()?r.Rh(e.b,Ro(l(Mn(sl(e.b),e.Lj()),19)).n,l(Mn(sl(e.b),e.Lj()).Hk(),29).kk(),o):r.Rh(e.b,ms(r.Dh(),Ro(l(Mn(sl(e.b),e.Lj()),19))),null,o):r.Rh(e.b,-1-e.Lj(),null,o))),o&&o.oj()),hh(e.b)&&e.Jj(e.Ij(9,n,f,t,!1)),f):n}function mvt(e){var t,n,r,a,o,f,g,w,E,C;for(r=new bt,f=new G(e.e.a);f.a0&&(f=b.Math.max(f,kft(e.C.b+r.d.b,a))),C=r,L=a,B=o;e.C&&e.C.c>0&&(z=B+e.C.c,E&&(z+=C.d.c),f=b.Math.max(f,(A1(),f0(H1),b.Math.abs(L-1)<=H1||L==1||isNaN(L)&&isNaN(1)?0:z/(1-L)))),n.n.b=0,n.a.a=f}function wvt(e,t){var n,r,a,o,f,g,w,E,C,L,B,z;if(n=l(Qo(e.b,t),127),w=l(l($i(e.r,t),21),87),w.dc()){n.n.d=0,n.n.a=0;return}for(E=e.u.Hc((Rl(),vp)),f=0,e.A.Hc((mh(),Cv))&&Wbt(e,t),g=w.Kc(),C=null,B=0,L=0;g.Ob();)r=l(g.Pb(),117),o=ze(Ge(r.b.of((zq(),pK)))),a=r.b.Mf().b,C?(z=L+C.d.a+e.w+r.d.d,f=b.Math.max(f,(A1(),f0(H1),b.Math.abs(B-o)<=H1||B==o||isNaN(B)&&isNaN(o)?0:z/(o-B)))):e.C&&e.C.d>0&&(f=b.Math.max(f,kft(e.C.d+r.d.d,o))),C=r,B=o,L=a;e.C&&e.C.a>0&&(z=L+e.C.a,E&&(z+=C.d.a),f=b.Math.max(f,(A1(),f0(H1),b.Math.abs(B-1)<=H1||B==1||isNaN(B)&&isNaN(1)?0:z/(1-B)))),n.n.d=0,n.a.b=f}function wMn(e,t,n,r,a,o,f,g){var w,E,C,L,B,z,V,J,te,fe;if(V=!1,E=H9e(n.q,t.f+t.b-n.q.f),z=r.f>t.b&&g,fe=a-(n.q.e+E-f),L=(w=ZA(r,fe,!1),w.a),z&&L>r.f)return!1;if(z){for(B=0,te=new G(t.d);te.a=(Sn(o,e.c.length),l(e.c[o],186)).e,!z&&L>t.b&&!C)?!1:((C||z||L<=t.b)&&(C&&L>t.b?(n.d=L,aN(n,spt(n,L))):(Egt(n.q,E),n.c=!0),aN(r,a-(n.s+n.r)),qN(r,n.q.e+n.q.d,t.f),bV(t,r),e.c.length>o&&(UN((Sn(o,e.c.length),l(e.c[o],186)),r),(Sn(o,e.c.length),l(e.c[o],186)).a.c.length==0&&t2(e,o)),V=!0),V)}function yvt(e,t,n){var r,a,o,f,g,w;for(this.g=e,g=t.d.length,w=n.d.length,this.d=We(wg,m2,10,g+w,0,1),f=0;f0?Xoe(this,this.f/this.a):L1(t.g,t.d[0]).a!=null&&L1(n.g,n.d[0]).a!=null?Xoe(this,(ze(L1(t.g,t.d[0]).a)+ze(L1(n.g,n.d[0]).a))/2):L1(t.g,t.d[0]).a!=null?Xoe(this,L1(t.g,t.d[0]).a):L1(n.g,n.d[0]).a!=null&&Xoe(this,L1(n.g,n.d[0]).a)}function yMn(e,t){var n,r,a,o,f,g,w,E,C,L;for(e.a=new Zst(nyn(LM)),r=new G(t.a);r.a=1&&(te-f>0&&L>=0?(w.n.a+=J,w.n.b+=o*f):te-f<0&&C>=0&&(w.n.a+=J*te,w.n.b+=o));e.o.a=t.a,e.o.b=t.b,rt(e,(Nt(),bv),(mh(),r=l(K0(BM),9),new Zh(r,l(c0(r,r.length),9),0)))}function EMn(e,t,n,r,a,o){var f;if(!(t==null||!Hce(t,TPe,CPe)))throw ue(new Yn("invalid scheme: "+t));if(!e&&!(n!=null&&pd(n,cl(35))==-1&&n.length>0&&(Xn(0,n.length),n.charCodeAt(0)!=47)))throw ue(new Yn("invalid opaquePart: "+n));if(e&&!(t!=null&&nO(EY,t.toLowerCase()))&&!(n==null||!Hce(n,$M,zM)))throw ue(new Yn(n5t+n));if(e&&t!=null&&nO(EY,t.toLowerCase())&&!nxn(n))throw ue(new Yn(n5t+n));if(!c5n(r))throw ue(new Yn("invalid device: "+r));if(!Gyn(a))throw f=a==null?"invalid segments: null":"invalid segment: "+qyn(a),ue(new Yn(f));if(!(o==null||pd(o,cl(35))==-1))throw ue(new Yn("invalid query: "+o))}function TMn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe;if(n.Ug("Network simplex layering",1),e.b=t,fe=l(Q(t,(Nt(),nM)),17).a*4,te=e.b.a,te.c.length<1){n.Vg();return}for(o=k_n(e,te),J=null,a=Rr(o,0);a.b!=a.d.c;){for(r=l(Br(a),15),g=fe*ua(b.Math.sqrt(r.gc())),f=F_n(r),ole(n3e(Tun(r3e(bae(f),g),J),!0),n.eh(1)),B=e.b.b,V=new G(f.a);V.a1)for(J=We(Vr,di,28,e.b.b.c.length,15,1),L=0,E=new G(e.b.b);E.a0){JV(e,n,0),n.a+=String.fromCharCode(r),a=G5n(t,o),JV(e,n,a),o+=a-1;continue}r==39?o+10&&V.a<=0){w.c.length=0,$n(w.c,V);break}z=V.i-V.d,z>=g&&(z>g&&(w.c.length=0,g=z),$n(w.c,V))}w.c.length!=0&&(f=l(jt(w,aU(a,w.c.length)),118),Me.a.Bc(f)!=null,f.g=C++,Tke(f,t,n,r),w.c.length=0)}for(te=e.c.length+1,B=new G(e);B.aia||t.o==wv&&C=g&&a<=w)g<=a&&o<=w?(n[C++]=a,n[C++]=o,r+=2):g<=a?(n[C++]=a,n[C++]=w,e.b[r]=w+1,f+=2):o<=w?(n[C++]=g,n[C++]=o,r+=2):(n[C++]=g,n[C++]=w,e.b[r]=w+1);else if(wAb)&&g<10);s3e(e.c,new Y7),Tvt(e),wgn(e.c),gMn(e.f)}function OMn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J;for(n=l(Q(e,(Nt(),Ms)),101),f=e.f,o=e.d,g=f.a+o.b+o.c,w=0-o.d-e.c.b,C=f.b+o.d+o.a-e.c.b,E=new bt,L=new bt,a=new G(t);a.a=2){for(w=Rr(n,0),f=l(Br(w),8),g=l(Br(w),8);g.a0&&SN(E,!0,(Js(),vc)),g.k==(Zn(),Us)&&cat(E),ki(e.f,g,t)}}function BMn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e;for(a=l(Q(e,(Qi(),gM)),27),E=Ii,C=Ii,g=lo,w=lo,Me=Rr(e.b,0);Me.b!=Me.d.c;)fe=l(Br(Me),40),z=fe.e,V=fe.f,E=b.Math.min(E,z.a-V.a/2),C=b.Math.min(C,z.b-V.b/2),g=b.Math.max(g,z.a+V.a/2),w=b.Math.max(w,z.b+V.b/2);for(B=l(at(a,(Hc(),gIe)),107),Te=Rr(e.b,0);Te.b!=Te.d.c;)fe=l(Br(Te),40),L=Q(fe,gM),De(L,207)&&(o=l(L,27),Qh(o,fe.e.a,fe.e.b),aP(o,fe));for(te=Rr(e.a,0);te.b!=te.d.c;)J=l(Br(te),65),r=l(Q(J,gM),74),r&&(t=J.a,n=l6(r,!0,!0),dP(t,n));$e=g-E+(B.b+B.c),f=w-C+(B.d+B.a),Rt(Bt(at(a,(pi(),C4))))||Gw(a,$e,f,!1,!1),Hi(a,t7,$e-(B.b+B.c)),Hi(a,e7,f-(B.d+B.a))}function Svt(e,t){var n,r,a,o,f,g,w,E,C,L;for(w=!0,a=0,E=e.g[t.p],C=t.o.b+e.o,n=e.d[t.p][2],rf(e.b,E,pt(l(jt(e.b,E),17).a-1+n)),rf(e.c,E,ze(Ge(jt(e.c,E)))-C+n*e.f),++E,E>=e.j?(++e.j,vt(e.b,pt(1)),vt(e.c,C)):(r=e.d[t.p][1],rf(e.b,E,pt(l(jt(e.b,E),17).a+1-r)),rf(e.c,E,ze(Ge(jt(e.c,E)))+C-r*e.f)),(e.r==(Nf(),AB)&&(l(jt(e.b,E),17).a>e.k||l(jt(e.b,E-1),17).a>e.k)||e.r==LB&&(ze(Ge(jt(e.c,E)))>e.n||ze(Ge(jt(e.c,E-1)))>e.n))&&(w=!1),f=new hr(dr(ka(t).a.Kc(),new j));jr(f);)o=l(xr(f),18),g=o.c.i,e.g[g.p]==E&&(L=Svt(e,g),a=a+l(L.a,17).a,w=w&&Rt(Bt(L.b)));return e.g[t.p]=E,a=a+e.d[t.p][0],new ca(pt(a),(Hn(),!!w))}function _vt(e,t){var n,r,a,o,f;n=ze(Ge(Q(t,(Nt(),x0)))),n<2&&rt(t,x0,2),r=l(Q(t,Rh),88),r==(Js(),J1)&&rt(t,Rh,zV(t)),a=l(Q(t,Vkt),17),a.a==0?rt(t,(ft(),Xx),new Uce):rt(t,(ft(),Xx),new VH(a.a)),o=Bt(Q(t,ZL)),o==null&&rt(t,ZL,(Hn(),qe(Q(t,bp))===qe((ip(),iC)))),Is(new bn(null,new kn(t.a,16)),new qp(e)),Is(Dc(new bn(null,new kn(t.b,16)),new u5),new n_(e)),f=new xvt(t),rt(t,(ft(),$6),f),qO(e.a),X0(e.a,(uo(),y0),l(Q(t,dv),188)),X0(e.a,vg,l(Q(t,pv),188)),X0(e.a,bu,l(Q(t,JL),188)),X0(e.a,_u,l(Q(t,yW),188)),X0(e.a,mc,B3n(l(Q(t,bp),223))),uye(e.a,DIn(t)),rt(t,K1e,bP(e.a,t))}function Rke(e,t,n,r,a){var o,f,g,w,E,C,L,B,z,V,J,te,fe;for(L=new Pr,f=new bt,Spt(e,n,e.d.Ag(),f,L),Spt(e,r,e.d.Bg(),f,L),e.b=.2*(J=D2t(Dc(new bn(null,new kn(f,16)),new Tte)),te=D2t(Dc(new bn(null,new kn(f,16)),new Cte)),b.Math.min(J,te)),o=0,g=0;g=2&&(fe=X2t(f,!0,B),!e.e&&(e.e=new sXe(e)),q5n(e.e,fe,f,e.b)),Ogt(f,B),qMn(f),z=-1,C=new G(f);C.ag)}function Avt(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te;for(E=gs,C=gs,g=ia,w=ia,B=new G(t.i);B.a-1){for(a=Rr(g,0);a.b!=a.d.c;)r=l(Br(a),131),r.v=f;for(;g.b!=0;)for(r=l(kue(g,0),131),n=new G(r.i);n.a-1){for(o=new G(g);o.a0)&&(Y(w,b.Math.min(w.o,a.o-1)),q(w,w.i-1),w.i==0&&$n(g.c,w))}}function Mvt(e,t,n,r,a){var o,f,g,w;return w=gs,f=!1,g=Lke(e,ma(new lt(t.a,t.b),e),Oi(new lt(n.a,n.b),a),ma(new lt(r.a,r.b),n)),o=!!g&&!(b.Math.abs(g.a-e.a)<=Zw&&b.Math.abs(g.b-e.b)<=Zw||b.Math.abs(g.a-t.a)<=Zw&&b.Math.abs(g.b-t.b)<=Zw),g=Lke(e,ma(new lt(t.a,t.b),e),n,a),g&&((b.Math.abs(g.a-e.a)<=Zw&&b.Math.abs(g.b-e.b)<=Zw)==(b.Math.abs(g.a-t.a)<=Zw&&b.Math.abs(g.b-t.b)<=Zw)||o?w=b.Math.min(w,eA(ma(g,n))):f=!0),g=Lke(e,ma(new lt(t.a,t.b),e),r,a),g&&(f||(b.Math.abs(g.a-e.a)<=Zw&&b.Math.abs(g.b-e.b)<=Zw)==(b.Math.abs(g.a-t.a)<=Zw&&b.Math.abs(g.b-t.b)<=Zw)||o)&&(w=b.Math.min(w,eA(ma(g,r)))),w}function Dvt(e){sw(e,new Xm(Uz(nw(Zv(tw(ew(new x1,Mb),A3t),"Minimizes the stress within a layout using stress majorization. Stress exists if the euclidean distance between a pair of nodes doesn't match their graph theoretic distance, that is, the shortest path between the two nodes. The method allows to specify individual edge lengths."),new y1),Yu))),gt(e,Mb,hL,It(lAe)),gt(e,Mb,cG,(Hn(),!0)),gt(e,Mb,x6,It(d8t)),gt(e,Mb,Px,It(g8t)),gt(e,Mb,Nx,It(p8t)),gt(e,Mb,fT,It(f8t)),gt(e,Mb,fL,It(fAe)),gt(e,Mb,dT,It(b8t)),gt(e,Mb,PEe,It(uAe)),gt(e,Mb,FEe,It(oAe)),gt(e,Mb,REe,It(cAe)),gt(e,Mb,jEe,It(hAe)),gt(e,Mb,BEe,It(TK))}function HMn(e){var t,n,r,a,o,f,g,w;for(t=null,r=new G(e);r.a0&&n.c==0&&(!t&&(t=new bt),$n(t.c,n));if(t)for(;t.c.length!=0;){if(n=l(t2(t,0),239),n.b&&n.b.c.length>0){for(o=(!n.b&&(n.b=new bt),new G(n.b));o.agc(e,n,0))return new ca(a,n)}else if(ze(L1(a.g,a.d[0]).a)>ze(L1(n.g,n.d[0]).a))return new ca(a,n)}for(g=(!n.e&&(n.e=new bt),n.e).Kc();g.Ob();)f=l(g.Pb(),239),w=(!f.b&&(f.b=new bt),f.b),Ey(0,w.c.length),x_(w.c,0,n),f.c==w.c.length&&$n(t.c,f)}return null}function VMn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe;for(t.Ug("Interactive crossing minimization",1),f=0,o=new G(e.b);o.a0&&(n+=w.n.a+w.o.a/2,++L),V=new G(w.j);V.a0&&(n/=L),fe=We(Na,Zo,28,r.a.c.length,15,1),g=0,E=new G(r.a);E.a=g&&a<=w)g<=a&&o<=w?r+=2:g<=a?(e.b[r]=w+1,f+=2):o<=w?(n[C++]=a,n[C++]=g-1,r+=2):(n[C++]=a,n[C++]=g-1,e.b[r]=w+1,f+=2);else if(w2?(C=new bt,ra(C,new Zp(fe,1,fe.b)),o=vwt(C,Me+e.a),Te=new Gue(o),pc(Te,t),$n(n.c,Te)):r?Te=l(cr(e.b,cg(t)),272):Te=l(cr(e.b,Eb(t)),272),w=cg(t),r&&(w=Eb(t)),f=H9n(te,w),E=Me+e.a,f.a?(E+=b.Math.abs(te.b-L.b),J=new lt(L.a,(L.b+te.b)/2)):(E+=b.Math.abs(te.a-L.a),J=new lt((L.a+te.a)/2,L.b)),r?ki(e.d,t,new nxe(Te,f,J,E)):ki(e.c,t,new nxe(Te,f,J,E)),ki(e.b,t,Te),V=(!t.n&&(t.n=new nt(ec,t,1,7)),t.n),z=new or(V);z.e!=z.i.gc();)B=l(gr(z),135),a=uP(e,B,!0,0,0),$n(n.c,a)}function UMn(e){var t,n,r,a,o,f,g;if(!e.A.dc()){if(e.A.Hc((mh(),iF))&&(l(Qo(e.b,(Ct(),Qn)),127).k=!0,l(Qo(e.b,Dr),127).k=!0,t=e.q!=(Ra(),Tg)&&e.q!=Mu,_z(l(Qo(e.b,ar),127),t),_z(l(Qo(e.b,er),127),t),_z(e.g,t),e.A.Hc(Cv)&&(l(Qo(e.b,Qn),127).j=!0,l(Qo(e.b,Dr),127).j=!0,l(Qo(e.b,ar),127).k=!0,l(Qo(e.b,er),127).k=!0,e.g.k=!0)),e.A.Hc(rF))for(e.a.j=!0,e.a.k=!0,e.g.j=!0,e.g.k=!0,g=e.B.Hc((Zl(),FM)),a=eue(),o=0,f=a.length;o0),l(C.a.Xb(C.c=--C.b),18));o!=r&&C.b>0;)e.a[o.p]=!0,e.a[r.p]=!0,o=(mr(C.b>0),l(C.a.Xb(C.c=--C.b),18));C.b>0&&ph(C)}}function Ovt(e,t,n){var r,a,o,f,g,w,E,C,L,B,z;if(!e.b)return!1;for(f=null,B=null,w=new Boe(null,null),a=1,w.a[1]=e.b,L=w;L.a[a];)E=a,g=B,B=L,L=L.a[a],r=e.a.Ne(t,L.d),a=r<0?0:1,r==0&&(!n.c||Jc(L.e,n.d))&&(f=L),!(L&&L.b)&&!oy(L.a[a])&&(oy(L.a[1-a])?B=B.a[E]=EV(L,a):oy(L.a[1-a])||(z=B.a[1-E],z&&(!oy(z.a[1-E])&&!oy(z.a[E])?(B.b=!1,z.b=!0,L.b=!0):(o=g.a[1]==B?1:0,oy(z.a[E])?g.a[o]=uct(B,E):oy(z.a[1-E])&&(g.a[o]=EV(B,E)),L.b=g.a[o].b=!0,g.a[o].a[0].b=!1,g.a[o].a[1].b=!1))));return f&&(n.b=!0,n.d=f.e,L!=f&&(C=new Boe(L.d,L.e),Wxn(e,w,f,C),B==f&&(B=C)),B.a[B.a[1]==L?1:0]=L.a[L.a[0]?0:1],--e.c),e.b=w.a[1],e.b&&(e.b.b=!1),n.b}function WMn(e){var t,n,r,a,o,f,g,w,E,C,L,B;for(a=new G(e.a.a.b);a.a0?a-=864e5:a+=864e5,w=new Kye(bo(Zc(t.q.getTime()),a))),C=new S5,E=e.a.length,o=0;o=97&&r<=122||r>=65&&r<=90){for(f=o+1;f=E)throw ue(new Yn("Missing trailing '"));f+1=14&&C<=16))?t.a._b(r)?(n.a?hi(n.a,n.b):n.a=new Th(n.d),N_(n.a,"[...]")):(g=jm(r),E=new U_(t),Jg(n,Pvt(g,E))):De(r,183)?Jg(n,Skn(l(r,183))):De(r,195)?Jg(n,hxn(l(r,195))):De(r,201)?Jg(n,x9n(l(r,201))):De(r,2111)?Jg(n,fxn(l(r,2111))):De(r,53)?Jg(n,Ckn(l(r,53))):De(r,376)?Jg(n,Hkn(l(r,376))):De(r,846)?Jg(n,Tkn(l(r,846))):De(r,109)&&Jg(n,Ekn(l(r,109))):Jg(n,r==null?ul:xc(r));return n.a?n.e.length==0?n.a.a:n.a.a+(""+n.e):n.c}function JE(e,t){var n,r,a,o;o=e.F,t==null?(e.F=null,CE(e,null)):(e.F=(nr(t),t),r=pd(t,cl(60)),r!=-1?(a=(Ga(0,r,t.length),t.substr(0,r)),pd(t,cl(46))==-1&&!vn(a,Cx)&&!vn(a,SL)&&!vn(a,GG)&&!vn(a,_L)&&!vn(a,AL)&&!vn(a,LL)&&!vn(a,ML)&&!vn(a,DL)&&(a=p5t),n=Rq(t,cl(62)),n!=-1&&(a+=""+(Xn(n+1,t.length+1),t.substr(n+1))),CE(e,a)):(a=t,pd(t,cl(46))==-1&&(r=pd(t,cl(91)),r!=-1&&(a=(Ga(0,r,t.length),t.substr(0,r))),!vn(a,Cx)&&!vn(a,SL)&&!vn(a,GG)&&!vn(a,_L)&&!vn(a,AL)&&!vn(a,LL)&&!vn(a,ML)&&!vn(a,DL)?(a=p5t,r!=-1&&(a+=""+(Xn(r,t.length+1),t.substr(r)))):a=t),CE(e,a),a==t&&(e.F=e.D))),e.Db&4&&!(e.Db&1)&&Ni(e,new _a(e,1,5,o,t))}function Bvt(e,t){var n,r,a,o,f,g,w,E,C,L;if(w=t.length-1,g=(Xn(w,t.length),t.charCodeAt(w)),g==93){if(f=pd(t,cl(91)),f>=0)return a=Z4n(e,(Ga(1,f,t.length),t.substr(1,f-1))),C=(Ga(f+1,w,t.length),t.substr(f+1,w-(f+1))),CIn(e,C,a)}else{if(n=-1,ZSe==null&&(ZSe=new RegExp("\\d")),ZSe.test(String.fromCharCode(g))&&(n=h4e(t,cl(46),w-1),n>=0)){r=l(Moe(e,Tht(e,(Ga(1,n,t.length),t.substr(1,n-1))),!1),61),E=0;try{E=Oh((Xn(n+1,t.length+1),t.substr(n+1)),lo,Ii)}catch(B){throw B=bs(B),De(B,130)?(o=B,ue(new nV(o))):ue(B)}if(E>16==-10?n=l(e.Cb,292).Yk(t,n):e.Db>>16==-15&&(!t&&(t=(Tn(),td)),!E&&(E=(Tn(),td)),e.Cb.Yh()&&(w=new Zg(e.Cb,1,13,E,t,f2(Xl(l(e.Cb,62)),e),!1),n?n.nj(w):n=w));else if(De(e.Cb,90))e.Db>>16==-23&&(De(t,90)||(t=(Tn(),Kf)),De(E,90)||(E=(Tn(),Kf)),e.Cb.Yh()&&(w=new Zg(e.Cb,1,10,E,t,f2(du(l(e.Cb,29)),e),!1),n?n.nj(w):n=w));else if(De(e.Cb,457))for(g=l(e.Cb,850),f=(!g.b&&(g.b=new Pz(new Vie)),g.b),o=(r=new qm(new Sr(f.a).a),new Bz(r));o.a.b;)a=l(Nw(o.a).ld(),89),n=ZE(a,SU(a,g),n)}return n}function ZMn(e,t){var n,r,a,o,f,g,w,E,C,L,B;for(f=Rt(Bt(at(e,(Nt(),b4)))),B=l(at(e,v4),21),w=!1,E=!1,L=new or((!e.c&&(e.c=new nt(Hl,e,9,9)),e.c));L.e!=L.i.gc()&&(!w||!E);){for(o=l(gr(L),123),g=0,a=rg(Lh(he(le(Fh,1),Rn,20,0,[(!o.d&&(o.d=new Ln(js,o,8,5)),o.d),(!o.e&&(o.e=new Ln(js,o,7,4)),o.e)])));jr(a)&&(r=l(xr(a),74),C=f&&qw(r)&&Rt(Bt(at(r,gv))),n=gvt((!r.b&&(r.b=new Ln(_r,r,4,7)),r.b),o)?e==ds(bc(l(Oe((!r.c&&(r.c=new Ln(_r,r,5,8)),r.c),0),84))):e==ds(bc(l(Oe((!r.b&&(r.b=new Ln(_r,r,4,7)),r.b),0),84))),!((C||n)&&(++g,g>1))););(g>0||B.Hc((Rl(),vp))&&(!o.n&&(o.n=new nt(ec,o,1,7)),o.n).i>0)&&(w=!0),g>1&&(E=!0)}w&&t.Fc((Ho(),vf)),E&&t.Fc((Ho(),UL))}function Fvt(e){var t,n,r,a,o,f,g,w,E,C,L,B;if(B=l(at(e,(pi(),kv)),21),B.dc())return null;if(g=0,f=0,B.Hc((mh(),iF))){for(C=l(at(e,_M),101),r=2,n=2,a=2,o=2,t=ds(e)?l(at(ds(e),xv),88):l(at(e,xv),88),E=new or((!e.c&&(e.c=new nt(Hl,e,9,9)),e.c));E.e!=E.i.gc();)if(w=l(gr(E),123),L=l(at(w,s7),64),L==(Ct(),Pc)&&(L=Eke(w,t),Hi(w,s7,L)),C==(Ra(),Mu))switch(L.g){case 1:r=b.Math.max(r,w.i+w.g);break;case 2:n=b.Math.max(n,w.j+w.f);break;case 3:a=b.Math.max(a,w.i+w.g);break;case 4:o=b.Math.max(o,w.j+w.f)}else switch(L.g){case 1:r+=w.g+2;break;case 2:n+=w.f+2;break;case 3:a+=w.g+2;break;case 4:o+=w.f+2}g=b.Math.max(r,a),f=b.Math.max(n,o)}return Gw(e,g,f,!0,!0)}function Sle(e,t,n,r,a){var o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e;for(Te=l(yc(lV(Fi(new bn(null,new kn(t.d,16)),new CYe(n)),new SYe(n)),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15),L=Ii,C=lo,w=new G(t.b.j);w.a0,E?E&&(B=fe.p,f?++B:--B,L=l(jt(fe.c.a,B),10),r=o0t(L),z=!(Xue(r,ot,n[0])||Dst(r,ot,n[0]))):z=!0),V=!1,Ze=t.D.i,Ze&&Ze.c&&g.e&&(C=f&&Ze.p>0||!f&&Ze.p=0){for(w=null,g=new Ua(C.a,E+1);g.bf?1:uw(isNaN(0),isNaN(f)))<0&&(f0(Nd),(b.Math.abs(f-1)<=Nd||f==1||isNaN(f)&&isNaN(1)?0:f<1?-1:f>1?1:uw(isNaN(f),isNaN(1)))<0)&&(f0(Nd),(b.Math.abs(0-g)<=Nd||g==0||isNaN(0)&&isNaN(g)?0:0g?1:uw(isNaN(0),isNaN(g)))<0)&&(f0(Nd),(b.Math.abs(g-1)<=Nd||g==1||isNaN(g)&&isNaN(1)?0:g<1?-1:g>1?1:uw(isNaN(g),isNaN(1)))<0)),o)}function sDn(e){var t,n,r,a;if(n=e.D!=null?e.D:e.B,t=pd(n,cl(91)),t!=-1){r=(Ga(0,t,n.length),n.substr(0,t)),a=new Up;do a.a+="[";while((t=Nk(n,91,++t))!=-1);vn(r,Cx)?a.a+="Z":vn(r,SL)?a.a+="B":vn(r,GG)?a.a+="C":vn(r,_L)?a.a+="D":vn(r,AL)?a.a+="F":vn(r,LL)?a.a+="I":vn(r,ML)?a.a+="J":vn(r,DL)?a.a+="S":(a.a+="L",a.a+=""+r,a.a+=";");try{return null}catch(o){if(o=bs(o),!De(o,63))throw ue(o)}}else if(pd(n,cl(46))==-1){if(vn(n,Cx))return ih;if(vn(n,SL))return Al;if(vn(n,GG))return kf;if(vn(n,_L))return Na;if(vn(n,AL))return B4;if(vn(n,LL))return Vr;if(vn(n,ML))return nm;if(vn(n,DL))return h7}return null}function aDn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St;for(e.e=t,g=aEn(t),ot=new bt,r=new G(g);r.a=0&&J=E.c.c.length?C=u6e((Zn(),Ps),Aa):C=u6e((Zn(),Aa),Aa),C*=2,o=n.a.g,n.a.g=b.Math.max(o,o+(C-o)),f=n.b.g,n.b.g=b.Math.max(f,f+(C-f)),a=t}}function lDn(e){var t,n,r,a;for(Is(Fi(new bn(null,new kn(e.a.b,16)),new Oj),new aee),U8n(e),Is(Fi(new bn(null,new kn(e.a.b,16)),new oee),new cee),e.c==(ip(),s9)&&(Is(Fi(Dc(new bn(null,new kn(new br(e.f),1)),new uee),new lee),new vYe(e)),Is(Fi(fc(Dc(Dc(new bn(null,new kn(e.d.b,16)),new hee),new Nj),new fee),new Pj),new yYe(e))),a=new lt(gs,gs),t=new lt(ia,ia),r=new G(e.a.b);r.a0&&(t.a+=Co),GU(l(gr(g),167),t);for(t.a+=Phe,w=new q8((!r.c&&(r.c=new Ln(_r,r,5,8)),r.c));w.e!=w.i.gc();)w.e>0&&(t.a+=Co),GU(l(gr(w),167),t);t.a+=")"}}function hDn(e,t,n){var r,a,o,f,g,w,E,C;for(w=new or((!e.a&&(e.a=new nt(Ai,e,10,11)),e.a));w.e!=w.i.gc();)for(g=l(gr(w),27),a=new hr(dr(cp(g).a.Kc(),new j));jr(a);){if(r=l(xr(a),74),!r.b&&(r.b=new Ln(_r,r,4,7)),!(r.b.i<=1&&(!r.c&&(r.c=new Ln(_r,r,5,8)),r.c.i<=1)))throw ue(new I8("Graph must not contain hyperedges."));if(!qA(r)&&g!=bc(l(Oe((!r.c&&(r.c=new Ln(_r,r,5,8)),r.c),0),84)))for(E=new jrt,pc(E,r),rt(E,(bb(),Hx),r),Aie(E,l(hc(zo(n.f,g)),153)),k8(E,l(cr(n,bc(l(Oe((!r.c&&(r.c=new Ln(_r,r,5,8)),r.c),0),84))),153)),vt(t.c,E),f=new or((!r.n&&(r.n=new nt(ec,r,1,7)),r.n));f.e!=f.i.gc();)o=l(gr(f),135),C=new zct(E,o.a),pc(C,o),rt(C,Hx,o),C.e.a=b.Math.max(o.g,1),C.e.b=b.Math.max(o.f,1),Ake(C),vt(t.d,C)}}function fDn(e,t,n){var r,a,o,f,g,w,E,C,L,B;switch(n.Ug("Node promotion heuristic",1),e.i=t,e.r=l(Q(t,(Nt(),zb)),243),e.r!=(Nf(),v3)&&e.r!=x4?jDn(e):hSn(e),C=l(Q(e.i,HMe),17).a,o=new hd,e.r.g){case 2:case 1:QE(e,o);break;case 3:for(e.r=LW,QE(e,o),w=0,g=new G(e.b);g.ae.k&&(e.r=AB,QE(e,o));break;case 4:for(e.r=LW,QE(e,o),E=0,a=new G(e.c);a.ae.n&&(e.r=LB,QE(e,o));break;case 6:B=ua(b.Math.ceil(e.g.length*C/100)),QE(e,new aYe(B));break;case 5:L=ua(b.Math.ceil(e.e*C/100)),QE(e,new oYe(L));break;case 8:xwt(e,!0);break;case 9:xwt(e,!1);break;default:QE(e,o)}e.r!=v3&&e.r!=x4?PCn(e,t):t_n(e,t),n.Vg()}function dDn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me;for(L=e.b,C=new Ua(L,0),by(C,new yu(e)),Te=!1,f=1;C.b0&&(B.d+=C.n.d,B.d+=C.d),B.a>0&&(B.a+=C.n.a,B.a+=C.d),B.b>0&&(B.b+=C.n.b,B.b+=C.d),B.c>0&&(B.c+=C.n.c,B.c+=C.d),B}function jvt(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V;for(B=n.d,L=n.c,o=new lt(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a),f=o.b,E=new G(e.a);E.a0&&(e.c[t.c.p][t.p].d+=Jl(e.i,24)*MP*.07000000029802322-.03500000014901161,e.c[t.c.p][t.p].a=e.c[t.c.p][t.p].d/e.c[t.c.p][t.p].b)}}function bDn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te;for(V=new G(e);V.ar.d,r.d=b.Math.max(r.d,t),g&&n&&(r.d=b.Math.max(r.d,r.a),r.a=r.d+a);break;case 3:n=t>r.a,r.a=b.Math.max(r.a,t),g&&n&&(r.a=b.Math.max(r.a,r.d),r.d=r.a+a);break;case 2:n=t>r.c,r.c=b.Math.max(r.c,t),g&&n&&(r.c=b.Math.max(r.b,r.c),r.b=r.c+a);break;case 4:n=t>r.b,r.b=b.Math.max(r.b,t),g&&n&&(r.b=b.Math.max(r.b,r.c),r.c=r.b+a)}}}function zvt(e,t){var n,r,a,o,f,g,w,E,C;return E="",t.length==0?e.ne(iEe,Rle,-1,-1):(C=$y(t),vn(C.substr(0,3),"at ")&&(C=(Xn(3,C.length+1),C.substr(3))),C=C.replace(/\[.*?\]/g,""),f=C.indexOf("("),f==-1?(f=C.indexOf("@"),f==-1?(E=C,C=""):(E=$y((Xn(f+1,C.length+1),C.substr(f+1))),C=$y((Ga(0,f,C.length),C.substr(0,f))))):(n=C.indexOf(")",f),E=(Ga(f+1,n,C.length),C.substr(f+1,n-(f+1))),C=$y((Ga(0,f,C.length),C.substr(0,f)))),f=pd(C,cl(46)),f!=-1&&(C=(Xn(f+1,C.length+1),C.substr(f+1))),(C.length==0||vn(C,"Anonymous function"))&&(C=Rle),g=Rq(E,cl(58)),a=h4e(E,cl(58),g-1),w=-1,r=-1,o=iEe,g!=-1&&a!=-1&&(o=(Ga(0,a,E.length),E.substr(0,a)),w=irt((Ga(a+1,g,E.length),E.substr(a+1,g-(a+1)))),r=irt((Xn(g+1,E.length+1),E.substr(g+1)))),e.ne(o,C,w,r))}function wDn(e){var t,n,r,a,o,f,g,w,E,C,L;for(E=new G(e);E.a0||C.j==er&&C.e.c.length-C.g.c.length<0)){t=!1;break}for(a=new G(C.g);a.a=E&&Ze>=te&&(B+=V.n.b+J.n.b+J.a.b-$e,++g));if(n)for(f=new G(Te.e);f.a=E&&Ze>=te&&(B+=V.n.b+J.n.b+J.a.b-$e,++g))}g>0&&(ot+=B/g,++z)}z>0?(t.a=a*ot/z,t.g=z):(t.a=0,t.g=0)}function xDn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St;for(o=e.f.b,B=o.a,C=o.b,V=e.e.g,z=e.e.f,F5(e.e,o.a,o.b),ot=B/V,St=C/z,E=new or(EH(e.e));E.e!=E.i.gc();)w=l(gr(E),135),Uu(w,w.i*ot),Gu(w,w.j*St);for(Te=new or(Xae(e.e));Te.e!=Te.i.gc();)fe=l(gr(Te),123),$e=fe.i,Ze=fe.j,$e>0&&Uu(fe,$e*ot),Ze>0&&Gu(fe,Ze*St);for(mA(e.b,new zg),t=new bt,g=new qm(new Sr(e.c).a);g.b;)f=Nw(g),r=l(f.ld(),74),n=l(f.md(),407).a,a=l6(r,!1,!1),L=Ngt(cg(r),QN(a),n),dP(L,a),Me=Kgt(r),Me&&gc(t,Me,0)==-1&&($n(t.c,Me),kat(Me,(mr(L.b!=0),l(L.a.a.c,8)),n));for(te=new qm(new Sr(e.d).a);te.b;)J=Nw(te),r=l(J.ld(),74),n=l(J.md(),407).a,a=l6(r,!1,!1),L=Ngt(Eb(r),AN(QN(a)),n),L=AN(L),dP(L,a),Me=Wgt(r),Me&&gc(t,Me,0)==-1&&($n(t.c,Me),kat(Me,(mr(L.b!=0),l(L.c.b.c,8)),n))}function qvt(e,t,n,r){var a,o,f,g,w;return g=new zke(t),fCn(g,r),a=!0,e&&e.pf((pi(),xv))&&(o=l(e.of((pi(),xv)),88),a=o==(Js(),J1)||o==uc||o==vc),zbt(g,!1),Vu(g.e.Rf(),new v4e(g,!1,a)),uoe(g,g.f,(t1(),Gc),(Ct(),Qn)),uoe(g,g.f,Kc,Dr),uoe(g,g.g,Gc,er),uoe(g,g.g,Kc,ar),bdt(g,Qn),bdt(g,Dr),wat(g,ar),wat(g,er),py(),f=g.A.Hc((mh(),A4))&&g.B.Hc((Zl(),aF))?N1t(g):null,f&&xun(g.a,f),vDn(g),w7n(g),y7n(g),UMn(g),w_n(g),G7n(g),Jce(g,Qn),Jce(g,Dr),XSn(g),wLn(g),n&&(e5n(g),K7n(g),Jce(g,ar),Jce(g,er),w=g.B.Hc((Zl(),FM)),Opt(g,w,Qn),Opt(g,w,Dr),Npt(g,w,ar),Npt(g,w,er),Is(new bn(null,new kn(new gi(g.i),0)),new Fc),Is(Fi(new bn(null,b5e(g.r).a.oc()),new xa),new Ba),oxn(g),g.e.Pf(g.o),Is(new bn(null,b5e(g.r).a.oc()),new ga)),g.o}function kDn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J;for(E=gs,r=new G(e.a.b);r.a1)for(z=new Ike(V,Me,r),to(Me,new Jet(e,z)),$n(f.c,z),L=Me.a.ec().Kc();L.Ob();)C=l(L.Pb(),42),al(o,C.b);if(g.a.gc()>1)for(z=new Ike(V,g,r),to(g,new Zet(e,z)),$n(f.c,z),L=g.a.ec().Kc();L.Ob();)C=l(L.Pb(),42),al(o,C.b)}}function SDn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe;if(J=e.n,te=e.o,B=e.d,L=ze(Ge(Py(e,(Nt(),ode)))),t){for(C=L*(t.gc()-1),z=0,w=t.Kc();w.Ob();)f=l(w.Pb(),10),C+=f.o.a,z=b.Math.max(z,f.o.b);for(fe=J.a-(C-te.a)/2,o=J.b-B.d+z,r=te.a/(t.gc()+1),a=r,g=t.Kc();g.Ob();)f=l(g.Pb(),10),f.n.a=fe,f.n.b=o-f.o.b,fe+=f.o.a+L,E=Q2t(f),E.n.a=f.o.a/2-E.a.a,E.n.b=f.o.b,V=l(Q(f,(ft(),rW)),12),V.e.c.length+V.g.c.length==1&&(V.n.a=a-V.a.a,V.n.b=0,Mc(V,e)),a+=r}if(n){for(C=L*(n.gc()-1),z=0,w=n.Kc();w.Ob();)f=l(w.Pb(),10),C+=f.o.a,z=b.Math.max(z,f.o.b);for(fe=J.a-(C-te.a)/2,o=J.b+te.b+B.a-z,r=te.a/(n.gc()+1),a=r,g=n.Kc();g.Ob();)f=l(g.Pb(),10),f.n.a=fe,f.n.b=o,fe+=f.o.a+L,E=Q2t(f),E.n.a=f.o.a/2-E.a.a,E.n.b=0,V=l(Q(f,(ft(),rW)),12),V.e.c.length+V.g.c.length==1&&(V.n.a=a-V.a.a,V.n.b=te.b,Mc(V,e)),a+=r}}function _Dn(e,t){var n,r,a,o,f,g;if(l(Q(t,(ft(),Lu)),21).Hc((Ho(),vf))){for(g=new G(t.a);g.a=0&&f0&&(l(Qo(e.b,t),127).a.b=n)}function IDn(e,t,n,r){var a,o,f,g,w,E,C,L,B,z,V,J;if(B=ze(Ge(Q(e,(Nt(),GT)))),z=ze(Ge(Q(e,KT))),L=ze(Ge(Q(e,y4))),g=e.o,o=l(jt(e.j,0),12),f=o.n,J=Y9n(o,L),!!J){if(t.Hc((Rl(),vp)))switch(l(Q(e,(ft(),Wc)),64).g){case 1:J.c=(g.a-J.b)/2-f.a,J.d=z;break;case 3:J.c=(g.a-J.b)/2-f.a,J.d=-z-J.a;break;case 2:n&&o.e.c.length==0&&o.g.c.length==0?(C=r?J.a:l(jt(o.f,0),72).o.b,J.d=(g.b-C)/2-f.b):J.d=g.b+z-f.b,J.c=-B-J.b;break;case 4:n&&o.e.c.length==0&&o.g.c.length==0?(C=r?J.a:l(jt(o.f,0),72).o.b,J.d=(g.b-C)/2-f.b):J.d=g.b+z-f.b,J.c=B}else if(t.Hc(Yb))switch(l(Q(e,(ft(),Wc)),64).g){case 1:case 3:J.c=f.a+B;break;case 2:case 4:n&&!o.c?(C=r?J.a:l(jt(o.f,0),72).o.b,J.d=(g.b-C)/2-f.b):J.d=f.b+z}for(a=J.d,E=new G(o.f);E.a=t.length)return{done:!0};var a=t[r++];return{value:[a,n.get(a)],done:!1}}}},LSn()||(e.prototype.createObject=function(){return{}},e.prototype.get=function(t){return this.obj[":"+t]},e.prototype.set=function(t,n){this.obj[":"+t]=n},e.prototype[lhe]=function(t){delete this.obj[":"+t]},e.prototype.keys=function(){var t=[];for(var n in this.obj)n.charCodeAt(0)==58&&t.push(n.substring(1));return t}),e}function Qi(){Qi=U,gM=new Ui(NEe),new vs("DEPTH",pt(0)),Pde=new vs("FAN",pt(0)),nIe=new vs(gyt,pt(0)),Vb=new vs("ROOT",(Hn(),!1)),Rde=new vs("LEFTNEIGHBOR",null),dTt=new vs("RIGHTNEIGHBOR",null),BW=new vs("LEFTSIBLING",null),jde=new vs("RIGHTSIBLING",null),Nde=new vs("DUMMY",!1),new vs("LEVEL",pt(0)),sIe=new vs("REMOVABLE_EDGES",new os),PB=new vs("XCOOR",pt(0)),BB=new vs("YCOOR",pt(0)),FW=new vs("LEVELHEIGHT",0),c1=new vs("LEVELMIN",0),k0=new vs("LEVELMAX",0),Bde=new vs("GRAPH_XMIN",0),Fde=new vs("GRAPH_YMIN",0),rIe=new vs("GRAPH_XMAX",0),iIe=new vs("GRAPH_YMAX",0),tIe=new vs("COMPACT_LEVEL_ASCENSION",!1),Ode=new vs("COMPACT_CONSTRAINTS",new bt),dM=new vs("ID",""),pM=new vs("POSITION",pt(0)),C2=new vs("PRELIM",0),JT=new vs("MODIFIER",0),QT=new Ui(S3t),NB=new Ui(_3t)}function BDn(e){kke();var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te;if(e==null)return null;if(L=e.length*8,L==0)return"";for(g=L%24,z=L/24|0,B=g!=0?z+1:z,o=null,o=We(kf,Ad,28,B*4,15,1),E=0,C=0,t=0,n=0,r=0,f=0,a=0,w=0;w>24,E=(t&3)<<24>>24,V=t&-128?(t>>2^192)<<24>>24:t>>2<<24>>24,J=n&-128?(n>>4^240)<<24>>24:n>>4<<24>>24,te=r&-128?(r>>6^252)<<24>>24:r>>6<<24>>24,o[f++]=N2[V],o[f++]=N2[J|E<<4],o[f++]=N2[C<<2|te],o[f++]=N2[r&63];return g==8?(t=e[a],E=(t&3)<<24>>24,V=t&-128?(t>>2^192)<<24>>24:t>>2<<24>>24,o[f++]=N2[V],o[f++]=N2[E<<4],o[f++]=61,o[f++]=61):g==16&&(t=e[a],n=e[a+1],C=(n&15)<<24>>24,E=(t&3)<<24>>24,V=t&-128?(t>>2^192)<<24>>24:t>>2<<24>>24,J=n&-128?(n>>4^240)<<24>>24:n>>4<<24>>24,o[f++]=N2[V],o[f++]=N2[J|E<<4],o[f++]=N2[C<<2],o[f++]=61),If(o,0,o.length)}function FDn(e,t){var n,r,a,o,f,g,w;if(e.e==0&&e.p>0&&(e.p=-(e.p-1)),e.p>lo&&c6e(t,e.p-Lb),f=t.q.getDate(),YO(t,1),e.k>=0&&C2n(t,e.k),e.c>=0?YO(t,e.c):e.k>=0?(w=new R7e(t.q.getFullYear()-Lb,t.q.getMonth(),35),r=35-w.q.getDate(),YO(t,b.Math.min(r,f))):YO(t,f),e.f<0&&(e.f=t.q.getHours()),e.b>0&&e.f<12&&(e.f+=12),bhn(t,e.f==24&&e.g?0:e.f),e.j>=0&&ovn(t,e.j),e.n>=0&&wvn(t,e.n),e.i>=0&&Qtt(t,bo(mo(KN(Zc(t.q.getTime()),b2),b2),e.i)),e.a&&(a=new Qz,c6e(a,a.q.getFullYear()-Lb-80),fse(Zc(t.q.getTime()),Zc(a.q.getTime()))&&c6e(t,a.q.getFullYear()-Lb+100)),e.d>=0){if(e.c==-1)n=(7+e.d-t.q.getDay())%7,n>3&&(n-=7),g=t.q.getMonth(),YO(t,t.q.getDate()+n),t.q.getMonth()!=g&&YO(t,t.q.getDate()+(n>0?-7:7));else if(t.q.getDay()!=e.d)return!1}return e.o>lo&&(o=t.q.getTimezoneOffset(),Qtt(t,bo(Zc(t.q.getTime()),(e.o-o)*60*b2))),!0}function Kvt(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e;if(a=Q(t,(ft(),zi)),!!De(a,207)){for(V=l(a,27),J=t.e,B=new Eo(t.c),o=t.d,B.a+=o.b,B.b+=o.d,$e=l(at(V,(Nt(),xW)),181),vl($e,(Zl(),uY))&&(z=l(at(V,WMe),107),Tie(z,o.a),mwe(z,o.d),Cie(z,o.b),x8(z,o.c)),n=new bt,C=new G(t.a);C.ar.c.length-1;)vt(r,new ca(y6,hCe));n=l(Q(a,$d),17).a,Ug(l(Q(e,y3),88))?(a.e.aze(Ge((Sn(n,r.c.length),l(r.c[n],42)).b))&&ct((Sn(n,r.c.length),l(r.c[n],42)),a.e.a+a.f.a)):(a.e.bze(Ge((Sn(n,r.c.length),l(r.c[n],42)).b))&&ct((Sn(n,r.c.length),l(r.c[n],42)),a.e.b+a.f.b))}for(o=Rr(e.b,0);o.b!=o.d.c;)a=l(Br(o),40),n=l(Q(a,(Hc(),$d)),17).a,rt(a,(Qi(),c1),Ge((Sn(n,r.c.length),l(r.c[n],42)).a)),rt(a,k0,Ge((Sn(n,r.c.length),l(r.c[n],42)).b));t.Vg()}function jDn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J;for(e.o=ze(Ge(Q(e.i,(Nt(),m3)))),e.f=ze(Ge(Q(e.i,vv))),e.j=e.i.b.c.length,g=e.j-1,B=0,e.k=0,e.n=0,e.b=O1(We(ro,dt,17,e.j,0,1)),e.c=O1(We(ta,dt,345,e.j,7,1)),f=new G(e.i.b);f.a0&&vt(e.q,C),vt(e.p,C);t-=r,z=w+t,E+=t*e.f,rf(e.b,g,pt(z)),rf(e.c,g,E),e.k=b.Math.max(e.k,z),e.n=b.Math.max(e.n,E),e.e+=t,t+=J}}function Ct(){Ct=U;var e;Pc=new wO(cL,0),Qn=new wO(nG,1),ar=new wO(yhe,2),Dr=new wO(xhe,3),er=new wO(khe,4),ed=(Cn(),new Ek((e=l(K0(Oo),9),new Zh(e,l(c0(e,e.length),9),0)))),_0=a2(rs(Qn,he(le(Oo,1),au,64,0,[]))),yf=a2(rs(ar,he(le(Oo,1),au,64,0,[]))),$h=a2(rs(Dr,he(le(Oo,1),au,64,0,[]))),Hf=a2(rs(er,he(le(Oo,1),au,64,0,[]))),hl=a2(rs(Qn,he(le(Oo,1),au,64,0,[Dr]))),Ju=a2(rs(ar,he(le(Oo,1),au,64,0,[er]))),A0=a2(rs(Qn,he(le(Oo,1),au,64,0,[er]))),zl=a2(rs(Qn,he(le(Oo,1),au,64,0,[ar]))),zh=a2(rs(Dr,he(le(Oo,1),au,64,0,[er]))),xf=a2(rs(ar,he(le(Oo,1),au,64,0,[Dr]))),ql=a2(rs(Qn,he(le(Oo,1),au,64,0,[ar,er]))),ll=a2(rs(ar,he(le(Oo,1),au,64,0,[Dr,er]))),fl=a2(rs(Qn,he(le(Oo,1),au,64,0,[Dr,er]))),_l=a2(rs(Qn,he(le(Oo,1),au,64,0,[ar,Dr]))),Du=a2(rs(Qn,he(le(Oo,1),au,64,0,[ar,Dr,er])))}function $Dn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St;for(t.Ug(K3t,1),J=new bt,ot=new bt,E=new G(e.b);E.a0&&(Me-=z),Oke(f,Me),C=0,B=new G(f.a);B.a0),g.a.Xb(g.c=--g.b)),w=.4*r*C,!o&&g.b0&&(w=(Xn(0,t.length),t.charCodeAt(0)),w!=64)){if(w==37&&(L=t.lastIndexOf("%"),E=!1,L!=0&&(L==B-1||(E=(Xn(L+1,t.length),t.charCodeAt(L+1)==46))))){if(f=(Ga(1,L,t.length),t.substr(1,L-1)),Me=vn("%",f)?null:Vke(f),r=0,E)try{r=Oh((Xn(L+2,t.length+1),t.substr(L+2)),lo,Ii)}catch($e){throw $e=bs($e),De($e,130)?(g=$e,ue(new nV(g))):ue($e)}for(te=m7e(e.Gh());te.Ob();)if(V=MV(te),De(V,519)&&(a=l(V,598),Te=a.d,(Me==null?Te==null:vn(Me,Te))&&r--==0))return a;return null}if(C=t.lastIndexOf("."),z=C==-1?t:(Ga(0,C,t.length),t.substr(0,C)),n=0,C!=-1)try{n=Oh((Xn(C+1,t.length+1),t.substr(C+1)),lo,Ii)}catch($e){if($e=bs($e),De($e,130))z=t;else throw ue($e)}for(z=vn("%",z)?null:Vke(z),J=m7e(e.Gh());J.Ob();)if(V=MV(J),De(V,197)&&(o=l(V,197),fe=o.xe(),(z==null?fe==null:vn(z,fe))&&n--==0))return o;return null}return Bvt(e,t)}function WDn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te;for(C=new Pr,w=new Cw,r=new G(e.a.a.b);r.at.d.c){if(z=e.c[t.a.d],te=e.c[L.a.d],z==te)continue;p0(s0(i0(a0(r0(new _f,1),100),z),te))}}}}}function YDn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot;if(B=l(l($i(e.r,t),21),87),t==(Ct(),ar)||t==er){Vvt(e,t);return}for(o=t==Qn?(Pw(),rB):(Pw(),iB),$e=t==Qn?(ol(),a1):(ol(),w0),n=l(Qo(e.b,t),127),r=n.i,a=r.c+Y5(he(le(Na,1),Zo,28,15,[n.n.b,e.C.b,e.k])),fe=r.c+r.b-Y5(he(le(Na,1),Zo,28,15,[n.n.c,e.C.c,e.k])),f=i3e(y4e(o),e.t),Te=t==Qn?ia:gs,L=B.Kc();L.Ob();)E=l(L.Pb(),117),!(!E.c||E.c.d.c.length<=0)&&(te=E.b.Mf(),J=E.e,z=E.c,V=z.i,V.b=(w=z.n,z.e.a+w.b+w.c),V.a=(g=z.n,z.e.b+g.d+g.a),UO($e,yEe),z.f=$e,Z0(z,(Bl(),v0)),V.c=J.a-(V.b-te.a)/2,Ze=b.Math.min(a,J.a),ot=b.Math.max(fe,J.a+te.a),V.cot&&(V.c=ot-V.b),vt(f.d,new Dae(V,h8e(f,V))),Te=t==Qn?b.Math.max(Te,J.b+E.b.Mf().b):b.Math.min(Te,J.b));for(Te+=t==Qn?e.t:-e.t,Me=M8e((f.e=Te,f)),Me>0&&(l(Qo(e.b,t),127).a.b=Me),C=B.Kc();C.Ob();)E=l(C.Pb(),117),!(!E.c||E.c.d.c.length<=0)&&(V=E.c.i,V.c-=E.e.a,V.d-=E.e.b)}function XDn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z;for(t=new Pr,w=new or(e);w.e!=w.i.gc();){for(g=l(gr(w),27),n=new Ks,ki(X0e,g,n),z=new Bp,a=l(yc(new bn(null,new vw(new hr(dr(sP(g).a.Kc(),new j)))),dst(z,Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)])))),85),Kht(n,l(a.xc((Hn(),!0)),16),new Y3),r=l(yc(Fi(l(a.xc(!1),15).Lc(),new $9),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[Ec]))),15),f=r.Kc();f.Ob();)o=l(f.Pb(),74),B=Kgt(o),B&&(E=l(hc(zo(t.f,B)),21),E||(E=bbt(B),ju(t.f,B,E)),Ka(n,E));for(a=l(yc(new bn(null,new vw(new hr(dr(cp(g).a.Kc(),new j)))),dst(z,Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[Ec])))),85),Kht(n,l(a.xc(!0),16),new c5),r=l(yc(Fi(l(a.xc(!1),15).Lc(),new Eh),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[Ec]))),15),L=r.Kc();L.Ob();)C=l(L.Pb(),74),B=Wgt(C),B&&(E=l(hc(zo(t.f,B)),21),E||(E=bbt(B),ju(t.f,B,E)),Ka(n,E))}}function QDn(e,t){ble();var n,r,a,o,f,g,w,E,C,L,B,z,V,J;if(w=iu(e,0)<0,w&&(e=r2(e)),iu(e,0)==0)switch(t){case 0:return"0";case 1:return sT;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return z=new tb,t<0?z.a+="0E+":z.a+="0E",z.a+=t==lo?"2147483648":""+-t,z.a}C=18,L=We(kf,Ad,28,C+1,15,1),n=C,J=e;do E=J,J=KN(J,10),L[--n]=Yr(bo(48,Df(E,mo(J,10))))&Zs;while(iu(J,0)!=0);if(a=Df(Df(Df(C,n),t),1),t==0)return w&&(L[--n]=45),If(L,n,C-n);if(t>0&&iu(a,-6)>=0){if(iu(a,0)>=0){for(o=n+Yr(a),g=C-1;g>=o;g--)L[g+1]=L[g];return L[++o]=46,w&&(L[--n]=45),If(L,n,C-n+1)}for(f=2;fse(f,bo(r2(a),1));f++)L[--n]=48;return L[--n]=46,L[--n]=48,w&&(L[--n]=45),If(L,n,C-n)}return V=n+1,r=C,B=new S5,w&&(B.a+="-"),r-V>=1?(hb(B,L[n]),B.a+=".",B.a+=If(L,n+1,C-n-1)):B.a+=If(L,n,C-n),B.a+="E",iu(a,0)>0&&(B.a+="+"),B.a+=""+Y_(a),B.a}function Gw(e,t,n,r,a){var o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot;if(te=new lt(e.g,e.f),J=a9e(e),J.a=b.Math.max(J.a,t),J.b=b.Math.max(J.b,n),ot=J.a/te.a,C=J.b/te.b,$e=J.a-te.a,w=J.b-te.b,r)for(f=ds(e)?l(at(ds(e),(pi(),xv)),88):l(at(e,(pi(),xv)),88),g=qe(at(e,(pi(),_M)))===qe((Ra(),Mu)),Te=new or((!e.c&&(e.c=new nt(Hl,e,9,9)),e.c));Te.e!=Te.i.gc();)switch(fe=l(gr(Te),123),Me=l(at(fe,s7),64),Me==(Ct(),Pc)&&(Me=Eke(fe,f),Hi(fe,s7,Me)),Me.g){case 1:g||Uu(fe,fe.i*ot);break;case 2:Uu(fe,fe.i+$e),g||Gu(fe,fe.j*C);break;case 3:g||Uu(fe,fe.i*ot),Gu(fe,fe.j+w);break;case 4:g||Gu(fe,fe.j*C)}if(F5(e,J.a,J.b),a)for(B=new or((!e.n&&(e.n=new nt(ec,e,1,7)),e.n));B.e!=B.i.gc();)L=l(gr(B),135),z=L.i+L.g/2,V=L.j+L.f/2,Ze=z/te.a,E=V/te.b,Ze+E>=1&&(Ze-E>0&&V>=0?(Uu(L,L.i+$e),Gu(L,L.j+w*E)):Ze-E<0&&z>=0&&(Uu(L,L.i+$e*Ze),Gu(L,L.j+w)));return Hi(e,(pi(),kv),(mh(),o=l(K0(BM),9),new Zh(o,l(c0(o,o.length),9),0))),new lt(ot,C)}function Qvt(e){sw(e,new Xm(Uz(nw(Zv(tw(ew(new x1,gf),"ELK Radial"),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new fu),gf))),gt(e,gf,_G,It(uCt)),gt(e,gf,Jy,It(lCt)),gt(e,gf,x6,It(sCt)),gt(e,gf,Px,It(aCt)),gt(e,gf,Nx,It(oCt)),gt(e,gf,fT,It(iCt)),gt(e,gf,fL,It(NIe)),gt(e,gf,dT,It(cCt)),gt(e,gf,Cfe,It(Jde)),gt(e,gf,Tfe,It(Zde)),gt(e,gf,NG,It(BIe)),gt(e,gf,Sfe,It(ege)),gt(e,gf,_fe,It(FIe)),gt(e,gf,MCe,It(RIe)),gt(e,gf,LCe,It(PIe)),gt(e,gf,CCe,It(qW)),gt(e,gf,SCe,It(HW)),gt(e,gf,_Ce,It(FB)),gt(e,gf,ACe,It(jIe)),gt(e,gf,TCe,It(OIe))}function KU(e){var t,n,r,a,o,f,g,w,E,C,L;if(e==null)throw ue(new gd(ul));if(E=e,o=e.length,w=!1,o>0&&(t=(Xn(0,e.length),e.charCodeAt(0)),(t==45||t==43)&&(e=(Xn(1,e.length+1),e.substr(1)),--o,w=t==45)),o==0)throw ue(new gd(Yw+E+'"'));for(;e.length>0&&(Xn(0,e.length),e.charCodeAt(0)==48);)e=(Xn(1,e.length+1),e.substr(1)),--o;if(o>(Amt(),b6t)[10])throw ue(new gd(Yw+E+'"'));for(a=0;a0&&(L=-parseInt((Ga(0,r,e.length),e.substr(0,r)),10),e=(Xn(r,e.length+1),e.substr(r)),o-=r,n=!1);o>=f;){if(r=parseInt((Ga(0,f,e.length),e.substr(0,f)),10),e=(Xn(f,e.length+1),e.substr(f)),o-=f,n)n=!1;else{if(iu(L,g)<0)throw ue(new gd(Yw+E+'"'));L=mo(L,C)}L=Df(L,r)}if(iu(L,0)>0)throw ue(new gd(Yw+E+'"'));if(!w&&(L=r2(L),iu(L,0)<0))throw ue(new gd(Yw+E+'"'));return L}function Vke(e){kle();var t,n,r,a,o,f,g,w;if(e==null)return null;if(a=pd(e,cl(37)),a<0)return e;for(w=new Th((Ga(0,a,e.length),e.substr(0,a))),t=We(Al,C6,28,4,15,1),g=0,r=0,f=e.length;aa+2&&mce((Xn(a+1,e.length),e.charCodeAt(a+1)),kPe,EPe)&&mce((Xn(a+2,e.length),e.charCodeAt(a+2)),kPe,EPe))if(n=vdn((Xn(a+1,e.length),e.charCodeAt(a+1)),(Xn(a+2,e.length),e.charCodeAt(a+2))),a+=2,r>0?(n&192)==128?t[g++]=n<<24>>24:r=0:n>=128&&((n&224)==192?(t[g++]=n<<24>>24,r=2):(n&240)==224?(t[g++]=n<<24>>24,r=3):(n&248)==240&&(t[g++]=n<<24>>24,r=4)),r>0){if(g==r){switch(g){case 2:{hb(w,((t[0]&31)<<6|t[1]&63)&Zs);break}case 3:{hb(w,((t[0]&15)<<12|(t[1]&63)<<6|t[2]&63)&Zs);break}}g=0,r=0}}else{for(o=0;o=2){if((!e.a&&(e.a=new nt(cs,e,6,6)),e.a).i==0)n=(rb(),a=new rk,a),qr((!e.a&&(e.a=new nt(cs,e,6,6)),e.a),n);else if((!e.a&&(e.a=new nt(cs,e,6,6)),e.a).i>1)for(B=new q8((!e.a&&(e.a=new nt(cs,e,6,6)),e.a));B.e!=B.i.gc();)jA(B);dP(t,l(Oe((!e.a&&(e.a=new nt(cs,e,6,6)),e.a),0),166))}if(L)for(r=new or((!e.a&&(e.a=new nt(cs,e,6,6)),e.a));r.e!=r.i.gc();)for(n=l(gr(r),166),E=new or((!n.a&&(n.a=new Ys(qh,n,5)),n.a));E.e!=E.i.gc();)w=l(gr(E),377),g.a=b.Math.max(g.a,w.a),g.b=b.Math.max(g.b,w.b);for(f=new or((!e.n&&(e.n=new nt(ec,e,1,7)),e.n));f.e!=f.i.gc();)o=l(gr(f),135),C=l(at(o,MM),8),C&&Qh(o,C.a,C.b),L&&(g.a=b.Math.max(g.a,o.i+o.g),g.b=b.Math.max(g.b,o.j+o.f));return g}function Zvt(e,t,n,r,a){var o,f,g;if(eht(e,t),f=t[0],o=co(n.c,0),g=-1,z7e(n))if(r>0){if(f+r>e.length)return!1;g=kU((Ga(0,f+r,e.length),e.substr(0,f+r)),t)}else g=kU(e,t);switch(o){case 71:return g=o6(e,f,he(le(zt,1),dt,2,6,[Rwt,jwt]),t),a.e=g,!0;case 77:return dSn(e,t,a,g,f);case 76:return gSn(e,t,a,g,f);case 69:return skn(e,t,f,a);case 99:return akn(e,t,f,a);case 97:return g=o6(e,f,he(le(zt,1),dt,2,6,["AM","PM"]),t),a.b=g,!0;case 121:return pSn(e,t,f,g,n,a);case 100:return g<=0?!1:(a.c=g,!0);case 83:return g<0?!1:x5n(g,f,t[0],a);case 104:g==12&&(g=0);case 75:case 72:return g<0?!1:(a.f=g,a.g=!1,!0);case 107:return g<0?!1:(a.f=g,a.g=!0,!0);case 109:return g<0?!1:(a.j=g,!0);case 115:return g<0?!1:(a.n=g,!0);case 90:if(fcn[w]&&(te=w),L=new G(e.a.b);L.a1;){if(a=aCn(t),L=o.g,V=l(at(t,vM),107),J=ze(Ge(at(t,KW))),(!t.a&&(t.a=new nt(Ai,t,10,11)),t.a).i>1&&ze(Ge(at(t,(ug(),cge))))!=gs&&(o.c+(V.b+V.c))/(o.b+(V.d+V.a))1&&ze(Ge(at(t,(ug(),oge))))!=gs&&(o.c+(V.b+V.c))/(o.b+(V.d+V.a))>J&&Hi(a,(ug(),T4),b.Math.max(ze(Ge(at(t,mM))),ze(Ge(at(a,T4)))-ze(Ge(at(t,oge))))),z=new Q3e(r,C),w=wwt(z,a,B),E=w.g,E>=L&&E==E){for(f=0;f<(!a.a&&(a.a=new nt(Ai,a,10,11)),a.a).i;f++)Gpt(e,l(Oe((!a.a&&(a.a=new nt(Ai,a,10,11)),a.a),f),27),l(Oe((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a),f),27));Sht(t,z),l2n(o,w.c),u2n(o,w.b)}--g}Hi(t,(ug(),ZT),o.b),Hi(t,Zx,o.c),n.Vg()}function tIn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te;for(t.Ug("Interactive node layering",1),n=new bt,B=new G(e.a);B.a=g){mr(Te.b>0),Te.a.Xb(Te.c=--Te.b);break}else te.a>w&&(r?(ra(r.b,te.b),r.a=b.Math.max(r.a,te.a),ph(Te)):(vt(te.b,C),te.c=b.Math.min(te.c,w),te.a=b.Math.max(te.a,g),r=te));r||(r=new GQe,r.c=w,r.a=g,by(Te,r),vt(r.b,C))}for(f=e.b,E=0,fe=new G(n);fe.az&&(o&&(ko(ot,B),ko(cn,pt(E.b-1))),oi=n.b,ws+=B+t,B=0,C=b.Math.max(C,n.b+n.c+ur)),Uu(g,oi),Gu(g,ws),C=b.Math.max(C,oi+ur+n.c),B=b.Math.max(B,L),oi+=ur+t;if(C=b.Math.max(C,r),jn=ws+B+n.a,jnDd,an=b.Math.abs(B.b-V.b)>Dd,(!n&&cn&&an||n&&(cn||an))&&ui(te.a,$e)),Ka(te.a,r),r.b==0?B=$e:B=(mr(r.b!=0),l(r.c.b.c,8)),z3n(z,L,J),Cft(a)==St&&(eo(St.i)!=a.a&&(J=new qa,n9e(J,eo(St.i),Te)),rt(te,Y1e,J)),E9n(z,te,Te),C.a.zc(z,C);po(te,Ze),Fa(te,St)}for(E=C.a.ec().Kc();E.Ob();)w=l(E.Pb(),18),po(w,null),Fa(w,null);t.Vg()}function iIn(e,t){var n,r,a,o,f,g,w,E,C,L,B;for(a=l(Q(e,(Hc(),y3)),88),C=a==(Js(),uc)||a==vc?Q1:vc,n=l(yc(Fi(new bn(null,new kn(e.b,16)),new pI),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15),w=l(yc(fc(n.Oc(),new dXe(t)),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[Ec]))),15),w.Gc(l(yc(fc(n.Oc(),new gXe(t)),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[Ec]))),16)),w.jd(new pXe(C)),B=new Kp(new bXe(a)),r=new Pr,g=w.Kc();g.Ob();)f=l(g.Pb(),240),E=l(f.a,40),Rt(Bt(f.c))?(B.a.zc(E,(Hn(),Pb))==null,new ba(B.a.Zc(E,!1)).a.gc()>0&&ki(r,E,l(new ba(B.a.Zc(E,!1)).a.Vc(),40)),new ba(B.a.ad(E,!0)).a.gc()>1&&ki(r,L1t(B,E),E)):(new ba(B.a.Zc(E,!1)).a.gc()>0&&(o=l(new ba(B.a.Zc(E,!1)).a.Vc(),40),qe(o)===qe(hc(zo(r.f,E)))&&l(Q(E,(Qi(),Ode)),15).Fc(o)),new ba(B.a.ad(E,!0)).a.gc()>1&&(L=L1t(B,E),qe(hc(zo(r.f,L)))===qe(E)&&l(Q(L,(Qi(),Ode)),15).Fc(E)),B.a.Bc(E)!=null)}function ewt(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e;if(e.gc()==1)return l(e.Xb(0),235);if(e.gc()<=0)return new KH;for(a=e.Kc();a.Ob();){for(n=l(a.Pb(),235),V=0,C=Ii,L=Ii,w=lo,E=lo,z=new G(n.e);z.ag&&(Me=0,$e+=f+fe,f=0),D_n(J,n,Me,$e),t=b.Math.max(t,Me+te.a),f=b.Math.max(f,te.b),Me+=te.a+fe;return J}function sIn(e){kke();var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te;if(e==null||(o=iV(e),V=O4n(o),V%4!=0))return null;if(J=V/4|0,J==0)return We(Al,C6,28,0,15,1);for(L=null,t=0,n=0,r=0,a=0,f=0,g=0,w=0,E=0,z=0,B=0,C=0,L=We(Al,C6,28,J*3,15,1);z>4)<<24>>24,L[B++]=((n&15)<<4|r>>2&15)<<24>>24,L[B++]=(r<<6|a)<<24>>24}return!eO(f=o[C++])||!eO(g=o[C++])?null:(t=nd[f],n=nd[g],w=o[C++],E=o[C++],nd[w]==-1||nd[E]==-1?w==61&&E==61?n&15?null:(te=We(Al,C6,28,z*3+1,15,1),pu(L,0,te,0,z*3),te[B]=(t<<2|n>>4)<<24>>24,te):w!=61&&E==61?(r=nd[w],r&3?null:(te=We(Al,C6,28,z*3+2,15,1),pu(L,0,te,0,z*3),te[B++]=(t<<2|n>>4)<<24>>24,te[B]=((n&15)<<4|r>>2&15)<<24>>24,te)):null:(r=nd[w],a=nd[E],L[B++]=(t<<2|n>>4)<<24>>24,L[B++]=((n&15)<<4|r>>2&15)<<24>>24,L[B++]=(r<<6|a)<<24>>24,L))}function aIn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze;for(t.Ug(K3t,1),V=l(Q(e,(Nt(),bp)),223),a=new G(e.b);a.a=2){for(J=!0,B=new G(o.j),n=l(re(B),12),z=null;B.a0)if(r=L.gc(),E=ua(b.Math.floor((r+1)/2))-1,a=ua(b.Math.ceil((r+1)/2))-1,t.o==Y1)for(C=a;C>=E;C--)t.a[$e.p]==$e&&(J=l(L.Xb(C),42),V=l(J.a,10),!W0(n,J.b)&&z>e.b.e[V.p]&&(t.a[V.p]=$e,t.g[$e.p]=t.g[V.p],t.a[$e.p]=t.g[$e.p],t.f[t.g[$e.p].p]=(Hn(),!!(Rt(t.f[t.g[$e.p].p])&$e.k==(Zn(),Aa))),z=e.b.e[V.p]));else for(C=E;C<=a;C++)t.a[$e.p]==$e&&(fe=l(L.Xb(C),42),te=l(fe.a,10),!W0(n,fe.b)&&z0&&(a=l(jt(te.c.a,ot-1),10),f=e.i[a.p],cn=b.Math.ceil(j5(e.n,a,te)),o=Ze.a.e-te.d.d-(f.a.e+a.o.b+a.d.a)-cn),E=gs,ot0&&St.a.e.e-St.a.a-(St.b.e.e-St.b.a)<0,V=Me.a.e.e-Me.a.a-(Me.b.e.e-Me.b.a)<0&&St.a.e.e-St.a.a-(St.b.e.e-St.b.a)>0,z=Me.a.e.e+Me.b.aSt.b.e.e+St.a.a,$e=0,!J&&!V&&(B?o+L>0?$e=L:E-r>0&&($e=r):z&&(o+g>0?$e=g:E-Te>0&&($e=Te))),Ze.a.e+=$e,Ze.b&&(Ze.d.e+=$e),!1))}function nwt(e,t,n){var r,a,o,f,g,w,E,C,L,B;if(r=new ef(t.Lf().a,t.Lf().b,t.Mf().a,t.Mf().b),a=new $8,e.c)for(f=new G(t.Rf());f.aE&&(r.a+=Mnt(We(kf,Ad,28,-E,15,1))),r.a+="Is",pd(w,cl(32))>=0)for(a=0;a=r.o.b/2}else Te=!L;Te?(fe=l(Q(r,(ft(),Qx)),15),fe?B?o=fe:(a=l(Q(r,Gx),15),a?fe.gc()<=a.gc()?o=fe:o=a:(o=new bt,rt(r,Gx,o))):(o=new bt,rt(r,Qx,o))):(a=l(Q(r,(ft(),Gx)),15),a?L?o=a:(fe=l(Q(r,Qx),15),fe?a.gc()<=fe.gc()?o=a:o=fe:(o=new bt,rt(r,Qx,o))):(o=new bt,rt(r,Gx,o))),o.Fc(e),rt(e,(ft(),rW),n),t.d==n?(Fa(t,null),n.e.c.length+n.g.c.length==0&&Mc(n,null),Tyn(n)):(po(t,null),n.e.c.length+n.g.c.length==0&&Mc(n,null)),Ch(t.a)}function lIn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur,oi,ws;for(n.Ug("MinWidth layering",1),z=t.b,St=t.a,ws=l(Q(t,(Nt(),zMe)),17).a,g=l(Q(t,qMe),17).a,e.b=ze(Ge(Q(t,x0))),e.d=gs,$e=new G(St);$e.a<$e.c.c.length;)Te=l(re($e),10),Te.k==(Zn(),Ps)&&(Bn=Te.o.b,e.d=b.Math.min(e.d,Bn));for(e.d=b.Math.max(1,e.d),cn=St.c.length,e.c=We(Vr,di,28,cn,15,1),e.f=We(Vr,di,28,cn,15,1),e.e=We(Na,Zo,28,cn,15,1),E=0,e.a=0,Ze=new G(St);Ze.a0?(E=0,te&&(E+=g),E+=(an-1)*f,Me&&(E+=g),cn&&Me&&(E=b.Math.max(E,MCn(Me,f,Te,St))),E=e.a&&(r=GAn(e,Te),C=b.Math.max(C,r.b),$e=b.Math.max($e,r.d),vt(g,new ca(Te,r)));for(cn=new bt,E=0;E0),te.a.Xb(te.c=--te.b),an=new yu(e.b),by(te,an),mr(te.b0){for(B=C<100?null:new nb(C),E=new T7e(t),V=E.g,fe=We(Vr,di,28,C,15,1),r=0,$e=new Lw(C),a=0;a=0;)if(z!=null?Pi(z,V[w]):qe(z)===qe(V[w])){fe.length<=r&&(te=fe,fe=We(Vr,di,28,2*fe.length,15,1),pu(te,0,fe,0,r)),fe[r++]=a,qr($e,V[w]);break e}if(z=z,qe(z)===qe(g))break}}if(E=$e,V=$e.g,C=r,r>fe.length&&(te=fe,fe=We(Vr,di,28,r,15,1),pu(te,0,fe,0,r)),r>0){for(Me=!0,o=0;o=0;)vx(e,fe[f]);if(r!=C){for(a=C;--a>=r;)vx(E,a);te=fe,fe=We(Vr,di,28,r,15,1),pu(te,0,fe,0,r)}t=E}}}else for(t=_7n(e,t),a=e.i;--a>=0;)t.Hc(e.g[a])&&(vx(e,a),Me=!0);if(Me){if(fe!=null){for(n=t.gc(),L=n==1?rA(e,4,t.Kc().Pb(),null,fe[0],J):rA(e,6,t,fe,fe[0],J),B=n<100?null:new nb(n),a=t.Kc();a.Ob();)z=a.Pb(),B=d4e(e,l(z,76),B);B?(B.nj(L),B.oj()):Ni(e.e,L)}else{for(B=Ofn(t.gc()),a=t.Kc();a.Ob();)z=a.Pb(),B=d4e(e,l(z,76),B);B&&B.oj()}return!0}else return!1}function dIn(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me;for(n=new xdt(t),n.a||q_n(t),E=jSn(t),w=new Cw,te=new Ebt,J=new G(t.a);J.a0||n.o==Y1&&a=n}function pIn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur;for(Me=t,Te=new Cw,$e=new Cw,C=Aw(Me,fSe),r=new Mat(e,n,Te,$e),P9n(r.a,r.b,r.c,r.d,C),w=(St=Te.i,St||(Te.i=new q5(Te,Te.c))),an=w.Kc();an.Ob();)for(cn=l(an.Pb(),166),a=l($i(Te,cn),21),J=a.Kc();J.Ob();)if(V=J.Pb(),Ze=l(X5(e.d,V),166),Ze)g=(!cn.e&&(cn.e=new Ln(cs,cn,10,9)),cn.e),qr(g,Ze);else throw f=Yg(Me,Pd),B=y4t+V+x4t+f,z=B+kT,ue(new dd(z));for(E=(ot=$e.i,ot||($e.i=new q5($e,$e.c))),jn=E.Kc();jn.Ob();)for(Bn=l(jn.Pb(),166),o=l($i($e,Bn),21),fe=o.Kc();fe.Ob();)if(te=fe.Pb(),Ze=l(X5(e.d,te),166),Ze)L=(!Bn.g&&(Bn.g=new Ln(cs,Bn,9,10)),Bn.g),qr(L,Ze);else throw f=Yg(Me,Pd),B=y4t+te+x4t+f,z=B+kT,ue(new dd(z));!n.b&&(n.b=new Ln(_r,n,4,7)),n.b.i!=0&&(!n.c&&(n.c=new Ln(_r,n,5,8)),n.c.i!=0)&&(!n.b&&(n.b=new Ln(_r,n,4,7)),n.b.i<=1&&(!n.c&&(n.c=new Ln(_r,n,5,8)),n.c.i<=1))&&(!n.a&&(n.a=new nt(cs,n,6,6)),n.a).i==1&&(ur=l(Oe((!n.a&&(n.a=new nt(cs,n,6,6)),n.a),0),166),!aue(ur)&&!oue(ur)&&(wV(ur,l(Oe((!n.b&&(n.b=new Ln(_r,n,4,7)),n.b),0),84)),yV(ur,l(Oe((!n.c&&(n.c=new Ln(_r,n,5,8)),n.c),0),84))))}function bIn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn;for(Me=e.a,$e=0,Ze=Me.length;$e0?(L=l(jt(B.c.a,f-1),10),cn=j5(e.b,B,L),te=B.n.b-B.d.d-(L.n.b+L.o.b+L.d.a+cn)):te=B.n.b-B.d.d,E=b.Math.min(te,E),f1&&(f=b.Math.min(f,b.Math.abs(l(ff(g.a,1),8).b-C.b)))));else for(J=new G(t.j);J.aa&&(o=B.a-a,f=Ii,r.c.length=0,a=B.a),B.a>=a&&($n(r.c,g),g.a.b>1&&(f=b.Math.min(f,b.Math.abs(l(ff(g.a,g.a.b-2),8).b-B.b)))));if(r.c.length!=0&&o>t.o.a/2&&f>t.o.b/2){for(z=new gu,Mc(z,t),la(z,(Ct(),Qn)),z.n.a=t.o.a/2,fe=new gu,Mc(fe,t),la(fe,Dr),fe.n.a=t.o.a/2,fe.n.b=t.o.b,w=new G(r);w.a=E.b?po(g,fe):po(g,z)):(E=l(odn(g.a),8),te=g.a.b==0?I1(g.c):l(o0(g.a),8),te.b>=E.b?Fa(g,fe):Fa(g,z)),L=l(Q(g,(Nt(),cc)),75),L&&Ny(L,E,!0);t.n.a=a-t.o.a/2}}function vIn(e,t,n){var r,a,o,f,g,w,E,C,L,B;for(g=Rr(e.b,0);g.b!=g.d.c;)if(f=l(Br(g),40),!vn(f.c,DG))for(E=HEn(f,e),t==(Js(),uc)||t==vc?Vs(E,new ene):Vs(E,new tne),w=E.c.length,r=0;r=0?z=gx(g):z=BN(gx(g)),e.qf(VT,z)),E=new qa,B=!1,e.pf(p3)?(Fye(E,l(e.of(p3),8)),B=!0):Ahn(E,f.a/2,f.b/2),z.g){case 4:rt(C,Qu,(hf(),$b)),rt(C,sW,(Vm(),P6)),C.o.b=f.b,J<0&&(C.o.a=-J),la(L,(Ct(),ar)),B||(E.a=f.a),E.a-=f.a;break;case 2:rt(C,Qu,(hf(),d4)),rt(C,sW,(Vm(),FT)),C.o.b=f.b,J<0&&(C.o.a=-J),la(L,(Ct(),er)),B||(E.a=0);break;case 1:rt(C,hv,(ep(),F6)),C.o.a=f.a,J<0&&(C.o.b=-J),la(L,(Ct(),Dr)),B||(E.b=f.b),E.b-=f.b;break;case 3:rt(C,hv,(ep(),Ux)),C.o.a=f.a,J<0&&(C.o.b=-J),la(L,(Ct(),Qn)),B||(E.b=0)}if(Fye(L.n,E),rt(C,p3,E),t==Tv||t==Tg||t==Mu){if(V=0,t==Tv&&e.pf(k2))switch(z.g){case 1:case 2:V=l(e.of(k2),17).a;break;case 3:case 4:V=-l(e.of(k2),17).a}else switch(z.g){case 4:case 2:V=o.b,t==Tg&&(V/=a.b);break;case 1:case 3:V=o.a,t==Tg&&(V/=a.a)}rt(C,l3,V)}return rt(C,Wc,z),C}function wIn(){c3e();function e(r){var a=this;this.dispatch=function(o){var f=o.data;switch(f.cmd){case"algorithms":var g=L8e((Cn(),new $a(new gi(Qb.b))));r.postMessage({id:f.id,data:g});break;case"categories":var w=L8e((Cn(),new $a(new gi(Qb.c))));r.postMessage({id:f.id,data:w});break;case"options":var E=L8e((Cn(),new $a(new gi(Qb.d))));r.postMessage({id:f.id,data:E});break;case"register":kMn(f.algorithms),r.postMessage({id:f.id});break;case"layout":QAn(f.graph,f.layoutOptions||{},f.options||{}),r.postMessage({id:f.id,data:f.graph});break}},this.saveDispatch=function(o){try{a.dispatch(o)}catch(f){r.postMessage({id:o.data.id,error:f})}}}function t(r){var a=this;this.dispatcher=new e({postMessage:function(o){a.onmessage({data:o})}}),this.postMessage=function(o){setTimeout(function(){a.dispatcher.saveDispatch({data:o})},0)}}if(typeof document===ghe&&typeof self!==ghe){var n=new e(self);self.onmessage=n.saveDispatch}else typeof d!==ghe&&d.exports&&(Object.defineProperty(p,"__esModule",{value:!0}),d.exports={default:t,Worker:t})}function cwt(e,t,n){var r,a,o,f,g,w,E,C,L,B;for(C=new op(n),pc(C,t),rt(C,(ft(),zi),t),C.o.a=t.g,C.o.b=t.f,C.n.a=t.i,C.n.b=t.j,vt(n.a,C),ki(e.a,t,C),((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a).i!=0||Rt(Bt(at(t,(Nt(),b4)))))&&rt(C,FLe,(Hn(),!0)),E=l(Q(n,Lu),21),L=l(Q(C,(Nt(),Ms)),101),L==(Ra(),Wb)?rt(C,Ms,Z1):L!=Z1&&E.Fc((Ho(),$T)),B=0,r=l(Q(n,Rh),88),w=new or((!t.c&&(t.c=new nt(Hl,t,9,9)),t.c));w.e!=w.i.gc();)g=l(gr(w),123),a=ds(t),(qe(at(a,yg))!==qe((Ed(),E2))||qe(at(a,dv))===qe((l2(),BT))||qe(at(a,dv))===qe((l2(),PT))||Rt(Bt(at(a,f3)))||qe(at(a,g4))!==qe((Km(),c4))||qe(at(a,zb))===qe((Nf(),v3))||qe(at(a,zb))===qe((Nf(),x4))||qe(at(a,pv))===qe((p2(),WT))||qe(at(a,pv))===qe((p2(),YT)))&&!Rt(Bt(at(t,fW)))&&Hi(g,Ki,pt(B++)),Rt(Bt(at(g,mv)))||LDn(e,g,C,E,r,L);for(f=new or((!t.n&&(t.n=new nt(ec,t,1,7)),t.n));f.e!=f.i.gc();)o=l(gr(f),135),!Rt(Bt(at(o,mv)))&&o.a&&vt(C.b,Oce(o));return Rt(Bt(Q(C,QL)))&&E.Fc((Ho(),eW)),Rt(Bt(Q(C,bW)))&&(E.Fc((Ho(),tW)),E.Fc(UL),rt(C,Ms,Z1)),C}function Lle(e,t,n,r,a,o,f){var g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur,oi,ws;for(J=0,Bn=0,E=new G(e.b);E.aJ&&(o&&(ko(ot,z),ko(cn,pt(C.b-1)),vt(e.d,V),g.c.length=0),oi=n.b,ws+=z+t,z=0,L=b.Math.max(L,n.b+n.c+ur)),$n(g.c,w),ddt(w,oi,ws),L=b.Math.max(L,oi+ur+n.c),z=b.Math.max(z,B),oi+=ur+t,V=w;if(ra(e.a,g),vt(e.d,l(jt(g,g.c.length-1),163)),L=b.Math.max(L,r),jn=ws+z+n.a,jna.d.d+a.d.a?C.f.d=!0:(C.f.d=!0,C.f.a=!0))),r.b!=r.d.c&&(t=n);C&&(o=l(cr(e.f,f.d.i),60),t.bo.d.d+o.d.a?C.f.d=!0:(C.f.d=!0,C.f.a=!0))}for(g=new hr(dr(ka(z).a.Kc(),new j));jr(g);)f=l(xr(g),18),f.a.b!=0&&(t=l(o0(f.a),8),f.d.j==(Ct(),Qn)&&(te=new QA(t,new lt(t.a,a.d.d),a,f),te.f.a=!0,te.a=f.d,$n(J.c,te)),f.d.j==Dr&&(te=new QA(t,new lt(t.a,a.d.d+a.d.a),a,f),te.f.d=!0,te.a=f.d,$n(J.c,te)))}return J}function CIn(e,t,n){var r,a,o,f,g,w,E,C,L,B;for(w=new bt,L=t.length,f=$7e(n),E=0;E=V&&(Te>V&&(z.c.length=0,V=Te),$n(z.c,f));z.c.length!=0&&(B=l(jt(z,aU(t,z.c.length)),131),jn.a.Bc(B)!=null,B.s=J++,R9e(B,an,ot),z.c.length=0)}for($e=e.c.length+1,g=new G(e);g.aBn.s&&(ph(n),al(Bn.i,r),r.c>0&&(r.a=Bn,vt(Bn.t,r),r.b=St,vt(St.i,r)))}function uwt(e,t,n,r,a){var o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn;for(J=new Bu(t.b),$e=new Bu(t.b),B=new Bu(t.b),cn=new Bu(t.b),te=new Bu(t.b),St=Rr(t,0);St.b!=St.d.c;)for(Ze=l(Br(St),12),g=new G(Ze.g);g.a0,fe=Ze.g.c.length>0,E&&fe?$n(B.c,Ze):E?$n(J.c,Ze):fe&&$n($e.c,Ze);for(V=new G(J);V.aTe.nh()-E.b&&(B=Te.nh()-E.b),z>Te.oh()-E.d&&(z=Te.oh()-E.d),C0){for(Me=Rr(e.f,0);Me.b!=Me.d.c;)Te=l(Br(Me),10),Te.p+=B-e.e;r9e(e),Ch(e.f),J9e(e,r,z)}else{for(ui(e.f,z),z.p=r,e.e=b.Math.max(e.e,r),o=new hr(dr(ka(z).a.Kc(),new j));jr(o);)a=l(xr(o),18),!a.c.i.c&&a.c.i.k==(Zn(),cu)&&(ui(e.f,a.c.i),a.c.i.p=r-1);e.c=r}else r9e(e),Ch(e.f),r=0,jr(new hr(dr(ka(z).a.Kc(),new j)))?(B=0,B=vdt(B,z),r=B+2,J9e(e,r,z)):(ui(e.f,z),z.p=0,e.e=b.Math.max(e.e,0),e.b=l(jt(e.d.b,0),30),e.c=0);for(e.f.b==0||r9e(e),e.d.a.c.length=0,fe=new bt,E=new G(e.d.b);E.a=48&&t<=57){for(r=t-48;a=48&&t<=57;)if(r=r*10+t-48,r<0)throw ue(new ri(ai((Jr(),CSe))))}else throw ue(new ri(ai((Jr(),K4t))));if(n=r,t==44){if(a>=e.j)throw ue(new ri(ai((Jr(),Y4t))));if((t=co(e.i,a++))>=48&&t<=57){for(n=t-48;a=48&&t<=57;)if(n=n*10+t-48,n<0)throw ue(new ri(ai((Jr(),CSe))));if(r>n)throw ue(new ri(ai((Jr(),X4t))))}else n=-1}if(t!=125)throw ue(new ri(ai((Jr(),W4t))));e.bm(a)?(o=(Di(),Di(),new Ty(9,o)),e.d=a+1):(o=(Di(),Di(),new Ty(3,o)),e.d=a),o.Om(r),o.Nm(n),Li(e)}}return o}function DIn(e){var t,n,r,a,o;switch(n=l(Q(e,(ft(),Lu)),21),t=Oq(v8t),a=l(Q(e,(Nt(),p4)),346),a==(rp(),A2)&&Dh(t,w8t),Rt(Bt(Q(e,ide)))?fi(t,(uo(),y0),(vo(),d1e)):fi(t,(uo(),bu),(vo(),d1e)),Q(e,(QH(),kM))!=null&&Dh(t,y8t),(Rt(Bt(Q(e,RMe)))||Rt(Bt(Q(e,NMe))))&&yl(t,(uo(),mc),(vo(),OAe)),l(Q(e,Rh),88).g){case 2:case 3:case 4:yl(fi(t,(uo(),y0),(vo(),PAe)),mc,NAe)}switch(n.Hc((Ho(),eW))&&yl(fi(fi(t,(uo(),y0),(vo(),IAe)),_u,MAe),mc,DAe),qe(Q(e,zb))!==qe((Nf(),AW))&&fi(t,(uo(),bu),(vo(),XAe)),n.Hc(nW)&&(fi(t,(uo(),y0),(vo(),eLe)),fi(t,vg,JAe),fi(t,bu,ZAe)),qe(Q(e,lW))!==qe((zE(),VL))&&qe(Q(e,bp))!==qe((ip(),JB))&&yl(t,(uo(),mc),(vo(),VAe)),Rt(Bt(Q(e,BMe)))&&fi(t,(uo(),bu),(vo(),HAe)),Rt(Bt(Q(e,ede)))&&fi(t,(uo(),bu),(vo(),tLe)),VTn(e)&&(qe(Q(e,p4))===qe(A2)?r=l(Q(e,TB),299):r=l(Q(e,Z1e),299),o=r==(vE(),R1e)?(vo(),QAe):(vo(),iLe),fi(t,(uo(),_u),o)),l(Q(e,lDe),388).g){case 1:fi(t,(uo(),_u),(vo(),nLe));break;case 2:yl(fi(fi(t,(uo(),bu),(vo(),SAe)),_u,_Ae),mc,AAe)}return qe(Q(e,yg))!==qe((Ed(),E2))&&fi(t,(uo(),bu),(vo(),rLe)),t}function dwt(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me;if(Hu(e.a,t)){if(W0(l(cr(e.a,t),49),n))return 1}else ki(e.a,t,new Ks);if(Hu(e.a,n)){if(W0(l(cr(e.a,n),49),t))return-1}else ki(e.a,n,new Ks);if(Hu(e.e,t)){if(W0(l(cr(e.e,t),49),n))return-1}else ki(e.e,t,new Ks);if(Hu(e.e,n)){if(W0(l(cr(e.a,n),49),t))return 1}else ki(e.e,n,new Ks);if(e.c==(Ed(),yde)||!ns(t,(ft(),Ki))||!ns(n,(ft(),Ki))){for(L=null,E=new G(t.j);E.af?WE(e,t,n):WE(e,n,t),af?1:0}return r=l(Q(t,(ft(),Ki)),17).a,o=l(Q(n,Ki),17).a,r>o?WE(e,t,n):WE(e,n,t),ro?1:0}function Kw(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te;if(n==null)return null;if(e.a!=t.jk())throw ue(new Yn(yT+t.xe()+t3));if(De(t,469)){if(te=kSn(l(t,685),n),!te)throw ue(new Yn(zfe+n+"' is not a valid enumerator of '"+t.xe()+"'"));return te}switch(o2((El(),io),t).Nl()){case 2:{n=Tu(n,!1);break}case 3:{n=Tu(n,!0);break}}if(r=o2(io,t).Jl(),r)return r.jk().wi().ti(r,n);if(B=o2(io,t).Ll(),B){for(te=new bt,E=Tce(n),C=0,L=E.length;C1)for(V=new q8((!e.a&&(e.a=new nt(cs,e,6,6)),e.a));V.e!=V.i.gc();)jA(V);for(f=l(Oe((!e.a&&(e.a=new nt(cs,e,6,6)),e.a),0),166),te=oi,oi>Ze+$e?te=Ze+$e:oiot+J?fe=ot+J:wsZe-$e&&teot-J&&feoi+ur?cn=oi+ur:Zews+St?an=ws+St:otoi-ur&&cnws-St&&ann&&(B=n-1),z=P2+Jl(t,24)*MP*L-L/2,z<0?z=1:z>r&&(z=r-1),a=(rb(),w=new AS,w),dV(a,B),fV(a,z),qr((!f.a&&(f.a=new Ys(qh,f,5)),f.a),a)}function gwt(e){sw(e,new Xm(nw(Zv(tw(ew(new x1,th),"ELK Rectangle Packing"),"Algorithm for packing of unconnected boxes, i.e. graphs without edges. The given order of the boxes is always preserved and the main reading direction of the boxes is left to right. The algorithm is divided into two phases. One phase approximates the width in which the rectangles can be placed. The next phase places the rectangles in rows using the previously calculated width as bounding width and bundles rectangles with a similar height in blocks. A compaction step reduces the size of the drawing. Finally, the rectangles are expanded to fill their bounding box and eliminate empty unused spaces."),new c8))),gt(e,th,Ox,1.3),gt(e,th,hT,(Hn(),!1)),gt(e,th,Xw,iOe),gt(e,th,Jy,15),gt(e,th,SG,It(DCt)),gt(e,th,x6,It(NCt)),gt(e,th,Px,It(BCt)),gt(e,th,Nx,It(FCt)),gt(e,th,fT,It(OCt)),gt(e,th,fL,It(lge)),gt(e,th,dT,It(RCt)),gt(e,th,jCe,It(cOe)),gt(e,th,$Ce,It(oOe)),gt(e,th,RCe,It(fge)),gt(e,th,FCe,It(uOe)),gt(e,th,zCe,It(rOe)),gt(e,th,qCe,It(hge)),gt(e,th,HCe,It(nOe)),gt(e,th,VCe,It(aOe)),gt(e,th,hL,It(tOe)),gt(e,th,AG,It(ICt)),gt(e,th,PCe,It(jB)),gt(e,th,NCe,It(eOe)),gt(e,th,BCe,It($B)),gt(e,th,OCe,It(sOe))}function Dle(e,t){ble();var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur,oi;if(cn=e.e,V=e.d,a=e.a,cn==0)switch(t){case 0:return"0";case 1:return sT;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return ot=new tb,t<0?ot.a+="0E+":ot.a+="0E",ot.a+=-t,ot.a}if(Me=V*10+1+7,$e=We(kf,Ad,28,Me+1,15,1),n=Me,V==1)if(g=a[0],g<0){oi=va(g,Vo);do J=oi,oi=KN(oi,10),$e[--n]=48+Yr(Df(J,mo(oi,10)))&Zs;while(iu(oi,0)!=0)}else{oi=g;do J=oi,oi=oi/10|0,$e[--n]=48+(J-oi*10)&Zs;while(oi!=0)}else{Bn=We(Vr,di,28,V,15,1),ur=V,pu(a,0,Bn,0,ur);e:for(;;){for(St=0,E=ur-1;E>=0;E--)jn=bo(l0(St,32),va(Bn[E],Vo)),fe=yxn(jn),Bn[E]=Yr(fe),St=Yr(bw(fe,32));Te=Yr(St),te=n;do $e[--n]=48+Te%10&Zs;while((Te=Te/10|0)!=0&&n!=0);for(r=9-te+n,w=0;w0;w++)$e[--n]=48;for(L=ur-1;Bn[L]==0;L--)if(L==0)break e;ur=L+1}for(;$e[n]==48;)++n}if(z=cn<0,f=Me-n-t-1,t==0)return z&&($e[--n]=45),If($e,n,Me-n);if(t>0&&f>=-6){if(f>=0){for(C=n+f,B=Me-1;B>=C;B--)$e[B+1]=$e[B];return $e[++C]=46,z&&($e[--n]=45),If($e,n,Me-n+1)}for(L=2;L<-f+1;L++)$e[--n]=48;return $e[--n]=46,$e[--n]=48,z&&($e[--n]=45),If($e,n,Me-n)}return an=n+1,o=Me,Ze=new S5,z&&(Ze.a+="-"),o-an>=1?(hb(Ze,$e[n]),Ze.a+=".",Ze.a+=If($e,n+1,Me-n-1)):Ze.a+=If($e,n,Me-n),Ze.a+="E",f>0&&(Ze.a+="+"),Ze.a+=""+f,Ze.a}function pwt(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot;switch(e.c=t,e.g=new Pr,n=(aw(),new Jv(e.c)),r=new e_(n),S8e(r),Me=ei(at(e.c,(YN(),AOe))),w=l(at(e.c,kge),324),Ze=l(at(e.c,Ege),437),f=l(at(e.c,COe),490),$e=l(at(e.c,xge),438),e.j=ze(Ge(at(e.c,JCt))),g=e.a,w.g){case 0:g=e.a;break;case 1:g=e.b;break;case 2:g=e.i;break;case 3:g=e.e;break;case 4:g=e.f;break;default:throw ue(new Yn(FG+(w.f!=null?w.f:""+w.g)))}if(e.d=new cot(g,Ze,f),rt(e.d,(pE(),jL),Bt(at(e.c,XCt))),e.d.c=Rt(Bt(at(e.c,SOe))),AH(e.c).i==0)return e.d;for(L=new or(AH(e.c));L.e!=L.i.gc();){for(C=l(gr(L),27),z=C.g/2,B=C.f/2,ot=new lt(C.i+z,C.j+B);Hu(e.g,ot);)dw(ot,(b.Math.random()-.5)*Dd,(b.Math.random()-.5)*Dd);J=l(at(C,(pi(),tC)),140),te=new kot(ot,new ef(ot.a-z-e.j/2-J.b,ot.b-B-e.j/2-J.d,C.g+e.j+(J.b+J.c),C.f+e.j+(J.d+J.a))),vt(e.d.i,te),ki(e.g,ot,new ca(te,C))}switch($e.g){case 0:if(Me==null)e.d.d=l(jt(e.d.i,0),68);else for(Te=new G(e.d.i);Te.a0?ur+1:1);for(f=new G(ot.g);f.a0?ur+1:1)}e.c[E]==0?ui(e.e,J):e.a[E]==0&&ui(e.f,J),++E}for(V=-1,z=1,L=new bt,e.d=l(Q(t,(ft(),Xx)),234);Hh>0;){for(;e.e.b!=0;)ws=l(kae(e.e),10),e.b[ws.p]=V--,pke(e,ws),--Hh;for(;e.f.b!=0;)Vl=l(kae(e.f),10),e.b[Vl.p]=z++,pke(e,Vl),--Hh;if(Hh>0){for(B=lo,Te=new G(Me);Te.a=B&&($e>B&&(L.c.length=0,B=$e),$n(L.c,J)));C=e.sg(L),e.b[C.p]=z++,pke(e,C),--Hh}}for(oi=Me.c.length+1,E=0;Ee.b[lc]&&(Uw(r,!0),rt(t,yB,(Hn(),!0)));e.a=null,e.c=null,e.b=null,Ch(e.f),Ch(e.e),n.Vg()}function bwt(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot;for(Ze=l(Oe((!e.a&&(e.a=new nt(cs,e,6,6)),e.a),0),166),C=new bl,$e=new Pr,ot=Cmt(Ze),ju($e.f,Ze,ot),B=new Pr,r=new os,V=rg(Lh(he(le(Fh,1),Rn,20,0,[(!t.d&&(t.d=new Ln(js,t,8,5)),t.d),(!t.e&&(t.e=new Ln(js,t,7,4)),t.e)])));jr(V);){if(z=l(xr(V),74),(!e.a&&(e.a=new nt(cs,e,6,6)),e.a).i!=1)throw ue(new Yn(n4t+(!e.a&&(e.a=new nt(cs,e,6,6)),e.a).i));z!=e&&(te=l(Oe((!z.a&&(z.a=new nt(cs,z,6,6)),z.a),0),166),Cs(r,te,r.c.b,r.c),J=l(hc(zo($e.f,te)),13),J||(J=Cmt(te),ju($e.f,te,J)),L=n?ma(new Eo(l(jt(ot,ot.c.length-1),8)),l(jt(J,J.c.length-1),8)):ma(new Eo((Sn(0,ot.c.length),l(ot.c[0],8))),(Sn(0,J.c.length),l(J.c[0],8))),ju(B.f,te,L))}if(r.b!=0)for(fe=l(jt(ot,n?ot.c.length-1:0),8),E=1;E1&&Cs(C,fe,C.c.b,C.c),Yoe(a)));fe=Te}return C}function mwt(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn;for(n.Ug(myt,1),Bn=l(yc(Fi(new bn(null,new kn(t,16)),new one),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15),C=l(yc(Fi(new bn(null,new kn(t,16)),new vXe(t)),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[Ec]))),15),V=l(yc(Fi(new bn(null,new kn(t,16)),new mXe(t)),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[Ec]))),15),J=We(PW,IG,40,t.gc(),0,1),f=0;f=0&&an=0&&!J[z]){J[z]=a,C.gd(g),--g;break}if(z=an-B,z=0&&!J[z]){J[z]=a,C.gd(g),--g;break}}for(V.jd(new cne),w=J.length-1;w>=0;w--)!J[w]&&!V.dc()&&(J[w]=l(V.Xb(0),40),V.gd(0));for(E=0;E=0;w--)ui(n,(Sn(w,f.c.length),l(f.c[w],8)));return n}function wwt(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e;for(Me=ze(Ge(at(t,(ug(),T4)))),z=ze(Ge(at(t,mM))),B=ze(Ge(at(t,UW))),v7e((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a)),fe=uvt((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a),Me,e.b),te=0;teB&&UN((Sn(B,t.c.length),l(t.c[B],186)),C),C=null;t.c.length>B&&(Sn(B,t.c.length),l(t.c[B],186)).a.c.length==0;)al(t,(Sn(B,t.c.length),t.c[B]));if(!C){--f;continue}if(!Rt(Bt(l(jt(C.b,0),27).of((z1(),$B))))&&tAn(t,V,o,C,te,n,B,r)){J=!0;continue}if(te){if(z=V.b,L=C.f,!Rt(Bt(l(jt(C.b,0),27).of($B)))&&wMn(t,V,o,C,n,B,r,a)){if(J=!0,z=e.j){e.a=-1,e.c=1;return}if(t=co(e.i,e.d++),e.a=t,e.b==1){switch(t){case 92:if(r=10,e.d>=e.j)throw ue(new ri(ai((Jr(),VG))));e.a=co(e.i,e.d++);break;case 45:(e.e&512)==512&&e.d=e.j||co(e.i,e.d)!=63)break;if(++e.d>=e.j)throw ue(new ri(ai((Jr(),e0e))));switch(t=co(e.i,e.d++),t){case 58:r=13;break;case 61:r=14;break;case 33:r=15;break;case 91:r=19;break;case 62:r=18;break;case 60:if(e.d>=e.j)throw ue(new ri(ai((Jr(),e0e))));if(t=co(e.i,e.d++),t==61)r=16;else if(t==33)r=17;else throw ue(new ri(ai((Jr(),L4t))));break;case 35:for(;e.d=e.j)throw ue(new ri(ai((Jr(),VG))));e.a=co(e.i,e.d++);break;default:r=0}e.c=r}function zIn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te;if(n.Ug("Process compaction",1),!!Rt(Bt(Q(t,(Hc(),uIe))))){for(a=l(Q(t,y3),88),z=ze(Ge(Q(t,zde))),gLn(e,t,a),iIn(t,z/2/2),V=t.b,$m(V,new lXe(a)),E=Rr(V,0);E.b!=E.d.c;)if(w=l(Br(E),40),!Rt(Bt(Q(w,(Qi(),Vb))))){if(r=$Sn(w,a),J=PAn(w,t),L=0,B=0,r)switch(te=r.e,a.g){case 2:L=te.a-z-w.f.a,J.e.a-z-w.f.aL&&(L=J.e.a+J.f.a+z),B=L+w.f.a;break;case 4:L=te.b-z-w.f.b,J.e.b-z-w.f.bL&&(L=J.e.b+J.f.b+z),B=L+w.f.b}else if(J)switch(a.g){case 2:L=J.e.a-z-w.f.a,B=L+w.f.a;break;case 1:L=J.e.a+J.f.a+z,B=L+w.f.a;break;case 4:L=J.e.b-z-w.f.b,B=L+w.f.b;break;case 3:L=J.e.b+J.f.b+z,B=L+w.f.b}qe(Q(t,$de))===qe((xA(),OB))?(o=L,f=B,g=kE(Fi(new bn(null,new kn(e.a,16)),new ttt(o,f))),g.a!=null?a==(Js(),uc)||a==vc?w.e.a=L:w.e.b=L:(a==(Js(),uc)||a==wf?g=kE(Fi(Dht(new bn(null,new kn(e.a,16))),new hXe(o))):g=kE(Fi(Dht(new bn(null,new kn(e.a,16))),new fXe(o))),g.a!=null&&(a==uc||a==vc?w.e.a=ze(Ge((mr(g.a!=null),l(g.a,42)).a)):w.e.b=ze(Ge((mr(g.a!=null),l(g.a,42)).a)))),g.a!=null&&(C=gc(e.a,(mr(g.a!=null),g.a),0),C>0&&C!=l(Q(w,$d),17).a&&(rt(w,tIe,(Hn(),!0)),rt(w,$d,pt(C))))):a==(Js(),uc)||a==vc?w.e.a=L:w.e.b=L}n.Vg()}}function ywt(e){var t,n,r,a,o,f,g,w,E;for(e.b=1,Li(e),t=null,e.c==0&&e.a==94?(Li(e),t=(Di(),Di(),new _h(4)),Eu(t,0,TT),g=new _h(4)):g=(Di(),Di(),new _h(4)),a=!0;(E=e.c)!=1;){if(E==0&&e.a==93&&!a){t&&(nL(t,g),g=t);break}if(n=e.a,r=!1,E==10)switch(n){case 100:case 68:case 119:case 87:case 115:case 83:Ky(g,YE(n)),r=!0;break;case 105:case 73:case 99:case 67:n=(Ky(g,YE(n)),-1),n<0&&(r=!0);break;case 112:case 80:if(w=w9e(e,n),!w)throw ue(new ri(ai((Jr(),t0e))));Ky(g,w),r=!0;break;default:n=eke(e)}else if(E==24&&!a){if(t&&(nL(t,g),g=t),o=ywt(e),nL(g,o),e.c!=0||e.a!=93)throw ue(new ri(ai((Jr(),j4t))));break}if(Li(e),!r){if(E==0){if(n==91)throw ue(new ri(ai((Jr(),ESe))));if(n==93)throw ue(new ri(ai((Jr(),TSe))));if(n==45&&!a&&e.a!=93)throw ue(new ri(ai((Jr(),n0e))))}if(e.c!=0||e.a!=45||n==45&&a)Eu(g,n,n);else{if(Li(e),(E=e.c)==1)throw ue(new ri(ai((Jr(),UG))));if(E==0&&e.a==93)Eu(g,n,n),Eu(g,45,45);else{if(E==0&&e.a==93||E==24)throw ue(new ri(ai((Jr(),n0e))));if(f=e.a,E==0){if(f==91)throw ue(new ri(ai((Jr(),ESe))));if(f==93)throw ue(new ri(ai((Jr(),TSe))));if(f==45)throw ue(new ri(ai((Jr(),n0e))))}else E==10&&(f=eke(e));if(Li(e),n>f)throw ue(new ri(ai((Jr(),q4t))));Eu(g,n,f)}}}a=!1}if(e.c==1)throw ue(new ri(ai((Jr(),UG))));return c6(g),eL(g),e.b=0,Li(e),g}function qIn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze;if(n.Ug("Coffman-Graham Layering",1),t.a.c.length==0){n.Vg();return}for(Ze=l(Q(t,(Nt(),$Me)),17).a,w=0,f=0,B=new G(t.a);B.a=Ze||!B5n(fe,r))&&(r=vat(t,C)),Va(fe,r),o=new hr(dr(ka(fe).a.Kc(),new j));jr(o);)a=l(xr(o),18),!e.a[a.p]&&(J=a.c.i,--e.e[J.p],e.e[J.p]==0&&K8($E(z,J),aT));for(E=C.c.length-1;E>=0;--E)vt(t.b,(Sn(E,C.c.length),l(C.c[E],30)));t.a.c.length=0,n.Vg()}function xwt(e,t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e;$e=!1;do for($e=!1,o=t?new br(e.a.b).a.gc()-2:1;t?o>=0:ol(Q(te,Ki),17).a)&&(Me=!1);if(Me){for(w=t?o+1:o-1,g=s6e(e.a,pt(w)),f=!1,Te=!0,r=!1,C=Rr(g,0);C.b!=C.d.c;)E=l(Br(C),10),ns(E,Ki)?E.p!=L.p&&(f=f|(t?l(Q(E,Ki),17).al(Q(L,Ki),17).a),Te=!1):!f&&Te&&E.k==(Zn(),cu)&&(r=!0,t?B=l(xr(new hr(dr(ka(E).a.Kc(),new j))),18).c.i:B=l(xr(new hr(dr(qs(E).a.Kc(),new j))),18).d.i,B==L&&(t?n=l(xr(new hr(dr(qs(E).a.Kc(),new j))),18).d.i:n=l(xr(new hr(dr(ka(E).a.Kc(),new j))),18).c.i,(t?l(dy(e.a,n),17).a-l(dy(e.a,B),17).a:l(dy(e.a,B),17).a-l(dy(e.a,n),17).a)<=2&&(Te=!1)));if(r&&Te&&(t?n=l(xr(new hr(dr(qs(L).a.Kc(),new j))),18).d.i:n=l(xr(new hr(dr(ka(L).a.Kc(),new j))),18).c.i,(t?l(dy(e.a,n),17).a-l(dy(e.a,L),17).a:l(dy(e.a,L),17).a-l(dy(e.a,n),17).a)<=2&&n.k==(Zn(),Ps)&&(Te=!1)),f||Te){for(J=J2t(e,L,t);J.a.gc()!=0;)V=l(J.a.ec().Kc().Pb(),10),J.a.Bc(V)!=null,Ka(J,J2t(e,V,t));--z,$e=!0}}}while($e)}function HIn(e){Wr(e.c,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#decimal"])),Wr(e.d,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#integer"])),Wr(e.e,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#boolean"])),Wr(e.f,li,he(le(zt,1),dt,2,6,[ho,"EBoolean",_i,"EBoolean:Object"])),Wr(e.i,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#byte"])),Wr(e.g,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#hexBinary"])),Wr(e.j,li,he(le(zt,1),dt,2,6,[ho,"EByte",_i,"EByte:Object"])),Wr(e.n,li,he(le(zt,1),dt,2,6,[ho,"EChar",_i,"EChar:Object"])),Wr(e.t,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#double"])),Wr(e.u,li,he(le(zt,1),dt,2,6,[ho,"EDouble",_i,"EDouble:Object"])),Wr(e.F,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#float"])),Wr(e.G,li,he(le(zt,1),dt,2,6,[ho,"EFloat",_i,"EFloat:Object"])),Wr(e.I,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#int"])),Wr(e.J,li,he(le(zt,1),dt,2,6,[ho,"EInt",_i,"EInt:Object"])),Wr(e.N,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#long"])),Wr(e.O,li,he(le(zt,1),dt,2,6,[ho,"ELong",_i,"ELong:Object"])),Wr(e.Z,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#short"])),Wr(e.$,li,he(le(zt,1),dt,2,6,[ho,"EShort",_i,"EShort:Object"])),Wr(e._,li,he(le(zt,1),dt,2,6,[ho,"http://www.w3.org/2001/XMLSchema#string"]))}function VIn(e,t,n,r,a,o,f){var g,w,E,C,L,B,z,V;return B=l(r.a,17).a,z=l(r.b,17).a,L=e.b,V=e.c,g=0,C=0,t==(Js(),uc)||t==vc?(C=fO(h1t(xy(fc(new bn(null,new kn(n.b,16)),new lne),new Yte))),L.e.b+L.f.b/2>C?(E=++z,g=ze(Ge(fh(vy(fc(new bn(null,new kn(n.b,16)),new itt(a,E)),new a$))))):(w=++B,g=ze(Ge(fh(Y8(fc(new bn(null,new kn(n.b,16)),new stt(a,w)),new Xte)))))):(C=fO(h1t(xy(fc(new bn(null,new kn(n.b,16)),new Zte),new s$))),L.e.a+L.f.a/2>C?(E=++z,g=ze(Ge(fh(vy(fc(new bn(null,new kn(n.b,16)),new ntt(a,E)),new Qte))))):(w=++B,g=ze(Ge(fh(Y8(fc(new bn(null,new kn(n.b,16)),new rtt(a,w)),new bI)))))),t==uc?(ko(e.a,new lt(ze(Ge(Q(L,(Qi(),c1))))-a,g)),ko(e.a,new lt(V.e.a+V.f.a+a+o,g)),ko(e.a,new lt(V.e.a+V.f.a+a+o,V.e.b+V.f.b/2)),ko(e.a,new lt(V.e.a+V.f.a,V.e.b+V.f.b/2))):t==vc?(ko(e.a,new lt(ze(Ge(Q(L,(Qi(),k0))))+a,L.e.b+L.f.b/2)),ko(e.a,new lt(L.e.a+L.f.a+a,g)),ko(e.a,new lt(V.e.a-a-o,g)),ko(e.a,new lt(V.e.a-a-o,V.e.b+V.f.b/2)),ko(e.a,new lt(V.e.a,V.e.b+V.f.b/2))):t==wf?(ko(e.a,new lt(g,ze(Ge(Q(L,(Qi(),c1))))-a)),ko(e.a,new lt(g,V.e.b+V.f.b+a+o)),ko(e.a,new lt(V.e.a+V.f.a/2,V.e.b+V.f.b+a+o)),ko(e.a,new lt(V.e.a+V.f.a/2,V.e.b+V.f.b+a))):(e.a.b==0||(l(o0(e.a),8).b=ze(Ge(Q(L,(Qi(),k0))))+a*l(f.b,17).a),ko(e.a,new lt(g,ze(Ge(Q(L,(Qi(),k0))))+a*l(f.b,17).a)),ko(e.a,new lt(g,V.e.b-a*l(f.a,17).a-o))),new ca(pt(B),pt(z))}function UIn(e){var t,n,r,a,o,f,g,w,E,C,L,B,z;if(f=!0,L=null,r=null,a=null,t=!1,z=P_t,E=null,o=null,g=0,w=Zce(e,g,TPe,CPe),w=0&&vn(e.substr(g,2),"//")?(g+=2,w=Zce(e,g,$M,zM),r=(Ga(g,w,e.length),e.substr(g,w-g)),g=w):L!=null&&(g==e.length||(Xn(g,e.length),e.charCodeAt(g)!=47))&&(f=!1,w=Lye(e,cl(35),g),w==-1&&(w=e.length),r=(Ga(g,w,e.length),e.substr(g,w-g)),g=w);if(!n&&g0&&co(C,C.length-1)==58&&(a=C,g=w)),gWue(o))&&(L=o);for(!L&&(L=(Sn(0,te.c.length),l(te.c[0],185))),J=new G(t.b);J.aL&&(jn=0,ur+=C+St,C=0),hmt(Ze,f,jn,ur),t=b.Math.max(t,jn+ot.a),C=b.Math.max(C,ot.b),jn+=ot.a+St;for($e=new Pr,n=new Pr,an=new G(e);an.a=-1900?1:0,n>=4?hi(e,he(le(zt,1),dt,2,6,[Rwt,jwt])[g]):hi(e,he(le(zt,1),dt,2,6,["BC","AD"])[g]);break;case 121:h6n(e,n,r);break;case 77:M_n(e,n,r);break;case 107:w=a.q.getHours(),w==0?ag(e,24,n):ag(e,w,n);break;case 83:HTn(e,n,a);break;case 69:C=r.q.getDay(),n==5?hi(e,he(le(zt,1),dt,2,6,["S","M","T","W","T","F","S"])[C]):n==4?hi(e,he(le(zt,1),dt,2,6,[Qle,Jle,Zle,ehe,the,nhe,rhe])[C]):hi(e,he(le(zt,1),dt,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[C]);break;case 97:a.q.getHours()>=12&&a.q.getHours()<24?hi(e,he(le(zt,1),dt,2,6,["AM","PM"])[1]):hi(e,he(le(zt,1),dt,2,6,["AM","PM"])[0]);break;case 104:L=a.q.getHours()%12,L==0?ag(e,12,n):ag(e,L,n);break;case 75:B=a.q.getHours()%12,ag(e,B,n);break;case 72:z=a.q.getHours(),ag(e,z,n);break;case 99:V=r.q.getDay(),n==5?hi(e,he(le(zt,1),dt,2,6,["S","M","T","W","T","F","S"])[V]):n==4?hi(e,he(le(zt,1),dt,2,6,[Qle,Jle,Zle,ehe,the,nhe,rhe])[V]):n==3?hi(e,he(le(zt,1),dt,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[V]):ag(e,V,1);break;case 76:J=r.q.getMonth(),n==5?hi(e,he(le(zt,1),dt,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[J]):n==4?hi(e,he(le(zt,1),dt,2,6,[$le,zle,qle,Hle,_x,Vle,Ule,Gle,Kle,Wle,Yle,Xle])[J]):n==3?hi(e,he(le(zt,1),dt,2,6,["Jan","Feb","Mar","Apr",_x,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[J]):ag(e,J+1,n);break;case 81:te=r.q.getMonth()/3|0,n<4?hi(e,he(le(zt,1),dt,2,6,["Q1","Q2","Q3","Q4"])[te]):hi(e,he(le(zt,1),dt,2,6,["1st quarter","2nd quarter","3rd quarter","4th quarter"])[te]);break;case 100:fe=r.q.getDate(),ag(e,fe,n);break;case 109:E=a.q.getMinutes(),ag(e,E,n);break;case 115:f=a.q.getSeconds(),ag(e,f,n);break;case 122:n<4?hi(e,o.c[0]):hi(e,o.c[1]);break;case 118:hi(e,o.b);break;case 90:n<3?hi(e,Bkn(o)):n==3?hi(e,zkn(o)):hi(e,qkn(o.a));break;default:return!1}return!0}function Wke(e,t,n,r){var a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur,oi;if(emt(t),w=l(Oe((!t.b&&(t.b=new Ln(_r,t,4,7)),t.b),0),84),C=l(Oe((!t.c&&(t.c=new Ln(_r,t,5,8)),t.c),0),84),g=bc(w),E=bc(C),f=(!t.a&&(t.a=new nt(cs,t,6,6)),t.a).i==0?null:l(Oe((!t.a&&(t.a=new nt(cs,t,6,6)),t.a),0),166),St=l(cr(e.a,g),10),jn=l(cr(e.a,E),10),cn=null,ur=null,De(w,193)&&(ot=l(cr(e.a,w),305),De(ot,12)?cn=l(ot,12):De(ot,10)&&(St=l(ot,10),cn=l(jt(St.j,0),12))),De(C,193)&&(Bn=l(cr(e.a,C),305),De(Bn,12)?ur=l(Bn,12):De(Bn,10)&&(jn=l(Bn,10),ur=l(jt(jn.j,0),12))),!St||!jn)throw ue(new I8("The source or the target of edge "+t+" could not be found. This usually happens when an edge connects a node laid out by ELK Layered to a node in another level of hierarchy laid out by either another instance of ELK Layered or another layout algorithm alltogether. The former can be solved by setting the hierarchyHandling option to INCLUDE_CHILDREN."));for(J=new Tw,pc(J,t),rt(J,(ft(),zi),t),rt(J,(Nt(),cc),null),z=l(Q(r,Lu),21),St==jn&&z.Fc((Ho(),GL)),cn||(Ze=(qo(),zu),an=null,f&&P5(l(Q(St,Ms),101))&&(an=new lt(f.j,f.k),Vct(an,WO(t)),vut(an,n),Ly(E,g)&&(Ze=$l,Oi(an,St.n))),cn=tvt(St,an,Ze,r)),ur||(Ze=(qo(),$l),oi=null,f&&P5(l(Q(jn,Ms),101))&&(oi=new lt(f.b,f.c),Vct(oi,WO(t)),vut(oi,n)),ur=tvt(jn,oi,Ze,eo(jn))),po(J,cn),Fa(J,ur),(cn.e.c.length>1||cn.g.c.length>1||ur.e.c.length>1||ur.g.c.length>1)&&z.Fc((Ho(),UL)),B=new or((!t.n&&(t.n=new nt(ec,t,1,7)),t.n));B.e!=B.i.gc();)if(L=l(gr(B),135),!Rt(Bt(at(L,mv)))&&L.a)switch(te=Oce(L),vt(J.b,te),l(Q(te,jd),278).g){case 1:case 2:z.Fc((Ho(),jT));break;case 0:z.Fc((Ho(),RT)),rt(te,jd,(F1(),nC))}if(o=l(Q(r,JL),322),fe=l(Q(r,yW),323),a=o==(dA(),mB)||fe==(OA(),vde),f&&(!f.a&&(f.a=new Ys(qh,f,5)),f.a).i!=0&&a){for(Te=QN(f),V=new bl,$e=Rr(Te,0);$e.b!=$e.d.c;)Me=l(Br($e),8),ui(V,new Eo(Me));rt(J,qLe,V)}return J}function YIn(e,t,n,r){var a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur,oi,ws;for(an=0,Bn=0,St=new Pr,Ze=l(fh(vy(fc(new bn(null,new kn(e.b,16)),new Jte),new sne)),17).a+1,cn=We(Vr,di,28,Ze,15,1),te=We(Vr,di,28,Ze,15,1),J=0;J1)for(g=ur+1;gE.b.e.b*(1-fe)+E.c.e.b*fe));V++);if(ot.gc()>0&&(oi=E.a.b==0?Ja(E.b.e):l(o0(E.a),8),Me=Oi(Ja(l(ot.Xb(ot.gc()-1),40).e),l(ot.Xb(ot.gc()-1),40).f),B=Oi(Ja(l(ot.Xb(0),40).e),l(ot.Xb(0),40).f),V>=ot.gc()-1&&oi.b>Me.b&&E.c.e.b>Me.b||V<=0&&oi.bE.b.e.a*(1-fe)+E.c.e.a*fe));V++);if(ot.gc()>0&&(oi=E.a.b==0?Ja(E.b.e):l(o0(E.a),8),Me=Oi(Ja(l(ot.Xb(ot.gc()-1),40).e),l(ot.Xb(ot.gc()-1),40).f),B=Oi(Ja(l(ot.Xb(0),40).e),l(ot.Xb(0),40).f),V>=ot.gc()-1&&oi.a>Me.a&&E.c.e.a>Me.a||V<=0&&oi.a=ze(Ge(Q(e,(Qi(),iIe))))&&++Bn):(z.f&&z.d.e.a<=ze(Ge(Q(e,(Qi(),Bde))))&&++an,z.g&&z.c.e.a+z.c.f.a>=ze(Ge(Q(e,(Qi(),rIe))))&&++Bn)}else $e==0?b9e(E):$e<0&&(++cn[ur],++te[ws],jn=VIn(E,t,e,new ca(pt(an),pt(Bn)),n,r,new ca(pt(te[ws]),pt(cn[ur]))),an=l(jn.a,17).a,Bn=l(jn.b,17).a)}function XIn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te;if(r=t,w=n,e.b&&r.j==(Ct(),er)&&w.j==(Ct(),er)&&(Te=r,r=w,w=Te),Hu(e.a,r)){if(W0(l(cr(e.a,r),49),w))return 1}else ki(e.a,r,new Ks);if(Hu(e.a,w)){if(W0(l(cr(e.a,w),49),r))return-1}else ki(e.a,w,new Ks);if(Hu(e.d,r)){if(W0(l(cr(e.d,r),49),w))return-1}else ki(e.d,r,new Ks);if(Hu(e.d,w)){if(W0(l(cr(e.a,w),49),r))return 1}else ki(e.d,w,new Ks);if(r.j!=w.j)return fe=Rln(r.j,w.j),fe==-1?df(e,w,r):df(e,r,w),fe;if(r.e.c.length!=0&&w.e.c.length!=0){if(e.b&&(fe=j0t(r,w),fe!=0))return fe==-1?df(e,w,r):fe==1&&df(e,r,w),fe;if(o=l(jt(r.e,0),18).c.i,C=l(jt(w.e,0),18).c.i,o==C)return a=l(Q(l(jt(r.e,0),18),(ft(),Ki)),17).a,E=l(Q(l(jt(w.e,0),18),Ki),17).a,a>E?df(e,r,w):df(e,w,r),aE?1:0;for(V=e.c,J=0,te=V.length;JE?df(e,r,w):df(e,w,r),aE?1:0):e.b&&(fe=j0t(r,w),fe!=0)?(fe==-1?df(e,w,r):fe==1&&df(e,r,w),fe):(f=0,L=0,ns(l(jt(r.g,0),18),Ki)&&(f=l(Q(l(jt(r.g,0),18),Ki),17).a),ns(l(jt(w.g,0),18),Ki)&&(L=l(Q(l(jt(r.g,0),18),Ki),17).a),g&&g==B?Rt(Bt(Q(l(jt(r.g,0),18),W1)))&&!Rt(Bt(Q(l(jt(w.g,0),18),W1)))?(df(e,r,w),1):!Rt(Bt(Q(l(jt(r.g,0),18),W1)))&&Rt(Bt(Q(l(jt(w.g,0),18),W1)))?(df(e,w,r),-1):(f>L?df(e,r,w):df(e,w,r),fL?1:0):(e.f&&(e.f._b(g)&&(f=l(e.f.xc(g),17).a),e.f._b(B)&&(L=l(e.f.xc(B),17).a)),f>L?df(e,r,w):df(e,w,r),fL?1:0))):r.e.c.length!=0&&w.g.c.length!=0?(df(e,r,w),1):r.g.c.length!=0&&w.e.c.length!=0?(df(e,w,r),-1):ns(r,(ft(),Ki))&&ns(w,Ki)?(a=l(Q(r,Ki),17).a,E=l(Q(w,Ki),17).a,a>E?df(e,r,w):df(e,w,r),aE?1:0):(df(e,w,r),-1)}function QIn(e){e.gb||(e.gb=!0,e.b=qc(e,0),Ss(e.b,18),is(e.b,19),e.a=qc(e,1),Ss(e.a,1),is(e.a,2),is(e.a,3),is(e.a,4),is(e.a,5),e.o=qc(e,2),Ss(e.o,8),Ss(e.o,9),is(e.o,10),is(e.o,11),is(e.o,12),is(e.o,13),is(e.o,14),is(e.o,15),is(e.o,16),is(e.o,17),is(e.o,18),is(e.o,19),is(e.o,20),is(e.o,21),is(e.o,22),is(e.o,23),sc(e.o),sc(e.o),sc(e.o),sc(e.o),sc(e.o),sc(e.o),sc(e.o),sc(e.o),sc(e.o),sc(e.o),e.p=qc(e,3),Ss(e.p,2),Ss(e.p,3),Ss(e.p,4),Ss(e.p,5),is(e.p,6),is(e.p,7),sc(e.p),sc(e.p),e.q=qc(e,4),Ss(e.q,8),e.v=qc(e,5),is(e.v,9),sc(e.v),sc(e.v),sc(e.v),e.w=qc(e,6),Ss(e.w,2),Ss(e.w,3),Ss(e.w,4),is(e.w,5),e.B=qc(e,7),is(e.B,1),sc(e.B),sc(e.B),sc(e.B),e.Q=qc(e,8),is(e.Q,0),sc(e.Q),e.R=qc(e,9),Ss(e.R,1),e.S=qc(e,10),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),sc(e.S),e.T=qc(e,11),is(e.T,10),is(e.T,11),is(e.T,12),is(e.T,13),is(e.T,14),sc(e.T),sc(e.T),e.U=qc(e,12),Ss(e.U,2),Ss(e.U,3),is(e.U,4),is(e.U,5),is(e.U,6),is(e.U,7),sc(e.U),e.V=qc(e,13),is(e.V,10),e.W=qc(e,14),Ss(e.W,18),Ss(e.W,19),Ss(e.W,20),is(e.W,21),is(e.W,22),is(e.W,23),e.bb=qc(e,15),Ss(e.bb,10),Ss(e.bb,11),Ss(e.bb,12),Ss(e.bb,13),Ss(e.bb,14),Ss(e.bb,15),Ss(e.bb,16),is(e.bb,17),sc(e.bb),sc(e.bb),e.eb=qc(e,16),Ss(e.eb,2),Ss(e.eb,3),Ss(e.eb,4),Ss(e.eb,5),Ss(e.eb,6),Ss(e.eb,7),is(e.eb,8),is(e.eb,9),e.ab=qc(e,17),Ss(e.ab,0),Ss(e.ab,1),e.H=qc(e,18),is(e.H,0),is(e.H,1),is(e.H,2),is(e.H,3),is(e.H,4),is(e.H,5),sc(e.H),e.db=qc(e,19),is(e.db,2),e.c=Ti(e,20),e.d=Ti(e,21),e.e=Ti(e,22),e.f=Ti(e,23),e.i=Ti(e,24),e.g=Ti(e,25),e.j=Ti(e,26),e.k=Ti(e,27),e.n=Ti(e,28),e.r=Ti(e,29),e.s=Ti(e,30),e.t=Ti(e,31),e.u=Ti(e,32),e.fb=Ti(e,33),e.A=Ti(e,34),e.C=Ti(e,35),e.D=Ti(e,36),e.F=Ti(e,37),e.G=Ti(e,38),e.I=Ti(e,39),e.J=Ti(e,40),e.L=Ti(e,41),e.M=Ti(e,42),e.N=Ti(e,43),e.O=Ti(e,44),e.P=Ti(e,45),e.X=Ti(e,46),e.Y=Ti(e,47),e.Z=Ti(e,48),e.$=Ti(e,49),e._=Ti(e,50),e.cb=Ti(e,51),e.K=Ti(e,52))}function JIn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur;for(f=new os,ot=l(Q(n,(Nt(),Rh)),88),J=0,Ka(f,(!t.a&&(t.a=new nt(Ai,t,10,11)),t.a));f.b!=0;)C=l(f.b==0?null:(mr(f.b!=0),af(f,f.a.a)),27),E=ds(C),(qe(at(E,yg))!==qe((Ed(),E2))||qe(at(E,dv))===qe((l2(),BT))||qe(at(E,dv))===qe((l2(),PT))||Rt(Bt(at(E,f3)))||qe(at(E,g4))!==qe((Km(),c4))||qe(at(E,zb))===qe((Nf(),v3))||qe(at(E,zb))===qe((Nf(),x4))||qe(at(E,pv))===qe((p2(),WT))||qe(at(E,pv))===qe((p2(),YT)))&&!Rt(Bt(at(C,fW)))&&Hi(C,(ft(),Ki),pt(J++)),fe=!Rt(Bt(at(C,mv))),fe&&(B=(!C.a&&(C.a=new nt(Ai,C,10,11)),C.a).i!=0,V=_xn(C),z=qe(at(C,p4))===qe((rp(),A2)),ur=!P1(C,(pi(),eC))||Sut(ei(at(C,eC))),$e=null,ur&&z&&(B||V)&&($e=Pmt(C),rt($e,Rh,ot),ns($e,CB)&&NJe(new D8e(ze(Ge(Q($e,CB)))),$e),l(at(C,bv),181).gc()!=0&&(L=$e,Is(new bn(null,(!C.c&&(C.c=new nt(Hl,C,9,9)),new kn(C.c,16))),new zWe(L)),_bt(C,$e))),St=n,cn=l(cr(e.a,ds(C)),10),cn&&(St=cn.e),Me=cwt(e,C,St),$e&&(Me.e=$e,$e.e=Me,Ka(f,(!C.a&&(C.a=new nt(Ai,C,10,11)),C.a))));for(J=0,Cs(f,t,f.c.b,f.c);f.b!=0;){for(o=l(f.b==0?null:(mr(f.b!=0),af(f,f.a.a)),27),w=new or((!o.b&&(o.b=new nt(js,o,12,3)),o.b));w.e!=w.i.gc();)g=l(gr(w),74),emt(g),(qe(at(t,yg))!==qe((Ed(),E2))||qe(at(t,dv))===qe((l2(),BT))||qe(at(t,dv))===qe((l2(),PT))||Rt(Bt(at(t,f3)))||qe(at(t,g4))!==qe((Km(),c4))||qe(at(t,zb))===qe((Nf(),v3))||qe(at(t,zb))===qe((Nf(),x4))||qe(at(t,pv))===qe((p2(),WT))||qe(at(t,pv))===qe((p2(),YT)))&&Hi(g,(ft(),Ki),pt(J++)),Bn=bc(l(Oe((!g.b&&(g.b=new Ln(_r,g,4,7)),g.b),0),84)),jn=bc(l(Oe((!g.c&&(g.c=new Ln(_r,g,5,8)),g.c),0),84)),!(Rt(Bt(at(g,mv)))||Rt(Bt(at(Bn,mv)))||Rt(Bt(at(jn,mv))))&&(te=qw(g)&&Rt(Bt(at(Bn,b4)))&&Rt(Bt(at(g,gv))),Ze=o,te||Ly(jn,Bn)?Ze=Bn:Ly(Bn,jn)&&(Ze=jn),St=n,cn=l(cr(e.a,Ze),10),cn&&(St=cn.e),Te=Wke(e,g,Ze,St),rt(Te,(ft(),RLe),JCn(e,g,t,n)));if(z=qe(at(o,p4))===qe((rp(),A2)),z)for(a=new or((!o.a&&(o.a=new nt(Ai,o,10,11)),o.a));a.e!=a.i.gc();)r=l(gr(a),27),ur=!P1(r,(pi(),eC))||Sut(ei(at(r,eC))),an=qe(at(r,p4))===qe(A2),ur&&an&&Cs(f,r,f.c.b,f.c)}}function ft(){ft=U;var e,t;zi=new Ui(NEe),RLe=new Ui("coordinateOrigin"),K1e=new Ui("processors"),FLe=new vs("compoundNode",(Hn(),!1)),xB=new vs("insideConnections",!1),qLe=new Ui("originalBendpoints"),HLe=new Ui("originalDummyNodePosition"),VLe=new Ui("originalLabelEdge"),WL=new Ui("representedLabels"),KL=new Ui("endLabels"),Kx=new Ui("endLabel.origin"),Yx=new vs("labelSide",(Ih(),eF)),R6=new vs("maxEdgeThickness",0),W1=new vs("reversed",!1),Xx=new Ui(C3t),o1=new vs("longEdgeSource",null),$f=new vs("longEdgeTarget",null),f4=new vs("longEdgeHasLabelDummies",!1),kB=new vs("longEdgeBeforeLabelDummy",!1),sW=new vs("edgeConstraint",(Vm(),M1e)),u3=new Ui("inLayerLayoutUnit"),hv=new vs("inLayerConstraint",(ep(),wB)),Wx=new vs("inLayerSuccessorConstraint",new bt),zLe=new vs("inLayerSuccessorConstraintBetweenNonDummies",!1),jl=new Ui("portDummy"),iW=new vs("crossingHint",pt(0)),Lu=new vs("graphProperties",(t=l(K0(F1e),9),new Zh(t,l(c0(t,t.length),9),0))),Wc=new vs("externalPortSide",(Ct(),Pc)),$Le=new vs("externalPortSize",new qa),q1e=new Ui("externalPortReplacedDummies"),aW=new Ui("externalPortReplacedDummy"),pp=new vs("externalPortConnections",(e=l(K0(Oo),9),new Zh(e,l(c0(e,e.length),9),0))),l3=new vs(b3t,0),BLe=new Ui("barycenterAssociates"),Qx=new Ui("TopSideComments"),Gx=new Ui("BottomSideComments"),rW=new Ui("CommentConnectionPort"),V1e=new vs("inputCollect",!1),G1e=new vs("outputCollect",!1),yB=new vs("cyclic",!1),jLe=new Ui("crossHierarchyMap"),Y1e=new Ui("targetOffset"),new vs("splineLabelSize",new qa),$6=new Ui("spacings"),oW=new vs("partitionConstraint",!1),c3=new Ui("breakingPoint.info"),KLe=new Ui("splines.survivingEdge"),fv=new Ui("splines.route.start"),z6=new Ui("splines.edgeChain"),GLe=new Ui("originalPortConstraints"),h3=new Ui("selfLoopHolder"),zT=new Ui("splines.nsPortY"),Ki=new Ui("modelOrder"),U1e=new Ui("longEdgeTargetNode"),jb=new vs(Q3t,!1),j6=new vs(Q3t,!1),H1e=new Ui("layerConstraints.hiddenNodes"),ULe=new Ui("layerConstraints.opposidePort"),W1e=new Ui("targetNode.modelOrder")}function ZIn(e,t,n,r){var a,o,f,g,w,E,C,L,B,z,V;for(L=Rr(e.b,0);L.b!=L.d.c;)if(C=l(Br(L),40),!vn(C.c,DG))for(o=l(yc(new bn(null,new kn(cEn(C,e),16)),Pl(new zr,new ht,new Fn,he(le(oc,1),it,108,0,[(Fl(),Ec)]))),15),t==(Js(),uc)||t==vc?o.jd(new nne):o.jd(new o$),V=o.gc(),a=0;a0&&(g=l(o0(l(o.Xb(a),65).a),8).a,B=C.e.a+C.f.a/2,w=l(o0(l(o.Xb(a),65).a),8).b,z=C.e.b+C.f.b/2,r>0&&b.Math.abs(w-z)/(b.Math.abs(g-B)/40)>50&&(z>w?ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a+r/5.3,C.e.b+C.f.b*f-r/2)):ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a+r/5.3,C.e.b+C.f.b*f+r/2)))),ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a,C.e.b+C.f.b*f))):t==vc?(E=ze(Ge(Q(C,(Qi(),c1)))),C.e.a-r>E?ko(l(o.Xb(a),65).a,new lt(E-n,C.e.b+C.f.b*f)):l(o.Xb(a),65).a.b>0&&(g=l(o0(l(o.Xb(a),65).a),8).a,B=C.e.a+C.f.a/2,w=l(o0(l(o.Xb(a),65).a),8).b,z=C.e.b+C.f.b/2,r>0&&b.Math.abs(w-z)/(b.Math.abs(g-B)/40)>50&&(z>w?ko(l(o.Xb(a),65).a,new lt(C.e.a-r/5.3,C.e.b+C.f.b*f-r/2)):ko(l(o.Xb(a),65).a,new lt(C.e.a-r/5.3,C.e.b+C.f.b*f+r/2)))),ko(l(o.Xb(a),65).a,new lt(C.e.a,C.e.b+C.f.b*f))):t==wf?(E=ze(Ge(Q(C,(Qi(),k0)))),C.e.b+C.f.b+r0&&(g=l(o0(l(o.Xb(a),65).a),8).a,B=C.e.a+C.f.a/2,w=l(o0(l(o.Xb(a),65).a),8).b,z=C.e.b+C.f.b/2,r>0&&b.Math.abs(g-B)/(b.Math.abs(w-z)/40)>50&&(B>g?ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f-r/2,C.e.b+r/5.3+C.f.b)):ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f+r/2,C.e.b+r/5.3+C.f.b)))),ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f,C.e.b+C.f.b))):(E=ze(Ge(Q(C,(Qi(),c1)))),C0t(l(o.Xb(a),65),e)?ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f,l(o0(l(o.Xb(a),65).a),8).b)):C.e.b-r>E?ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f,E-n)):l(o.Xb(a),65).a.b>0&&(g=l(o0(l(o.Xb(a),65).a),8).a,B=C.e.a+C.f.a/2,w=l(o0(l(o.Xb(a),65).a),8).b,z=C.e.b+C.f.b/2,r>0&&b.Math.abs(g-B)/(b.Math.abs(w-z)/40)>50&&(B>g?ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f-r/2,C.e.b-r/5.3)):ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f+r/2,C.e.b-r/5.3)))),ko(l(o.Xb(a),65).a,new lt(C.e.a+C.f.a*f,C.e.b)))}function pi(){pi=U;var e,t;eC=new Ui(Byt),a7=new Ui(Fyt),eNe=(og(),Sge),ASt=new pn(qTe,eNe),Z6=new pn(Ox,null),LSt=new Ui(tSe),nNe=(Ym(),rs(Lge,he(le(Mge,1),it,298,0,[Age]))),UB=new pn(SG,nNe),GB=new pn(VP,(Hn(),!1)),rNe=(Js(),J1),xv=new pn(gfe,rNe),aNe=(ip(),Hge),sNe=new pn(HP,aNe),ISt=new pn(ZCe,!1),uNe=(rp(),oY),n7=new pn(CG,uNe),vNe=new lw(12),_2=new pn(Xw,vNe),WB=new pn(hL,!1),Nge=new pn(AG,!1),YB=new pn(fL,!1),ENe=(Ra(),Wb),_M=new pn(Nhe,ENe),n9=new Ui(_G),XB=new Ui(NP),zge=new Ui(oG),qge=new Ui(lL),lNe=new bl,x3=new pn(ZTe,lNe),DSt=new pn(nCe,!1),OSt=new pn(rCe,!1),hNe=new s_,tC=new pn(sCe,hNe),rY=new pn($Te,!1),FSt=new pn(Ryt,1),t7=new Ui(jyt),e7=new Ui($yt),AM=new pn(PP,!1),new pn(zyt,!0),pt(0),new pn(qyt,pt(100)),new pn(Hyt,!1),pt(0),new pn(Vyt,pt(4e3)),pt(0),new pn(Uyt,pt(400)),new pn(Gyt,!1),new pn(Kyt,!1),new pn(Wyt,!0),new pn(Yyt,!1),tNe=(VV(),Kge),MSt=new pn(eSe,tNe),RSt=new pn(LTe,10),jSt=new pn(MTe,10),_Ne=new pn(_he,20),$St=new pn(DTe,10),ANe=new pn(Ohe,2),LNe=new pn(dfe,10),MNe=new pn(ITe,0),iY=new pn(PTe,5),DNe=new pn(OTe,1),INe=new pn(NTe,1),Ev=new pn(Jy,20),zSt=new pn(BTe,10),PNe=new pn(FTe,10),r9=new Ui(RTe),NNe=new nnt,ONe=new pn(aCe,NNe),PSt=new Ui(bfe),wNe=!1,NSt=new pn(pfe,wNe),dNe=new lw(5),fNe=new pn(UTe,dNe),gNe=(qy(),t=l(K0(Ko),9),new Zh(t,l(c0(t,t.length),9),0)),r7=new pn(fT,gNe),xNe=(t6(),Kb),yNe=new pn(WTe,xNe),Bge=new Ui(YTe),Fge=new Ui(XTe),Rge=new Ui(QTe),Pge=new Ui(JTe),pNe=(e=l(K0(BM),9),new Zh(e,l(c0(e,e.length),9),0)),kv=new pn(x6,pNe),mNe=un((Zl(),aC)),Ub=new pn(Nx,mNe),bNe=new lt(0,0),i7=new pn(Px,bNe),C4=new pn(hT,!1),iNe=(F1(),nC),Ige=new pn(eCe,iNe),Dge=new pn(cG,!1),pt(1),new pn(Xyt,null),kNe=new Ui(iCe),jge=new Ui(tCe),SNe=(Ct(),Pc),s7=new pn(zTe,SNe),rh=new Ui(jTe),TNe=(Rl(),un(Yb)),S4=new pn(dT,TNe),$ge=new pn(GTe,!1),CNe=new pn(KTe,!0),aY=new pn(BP,1),BNe=new pn(nSe,null),QB=new pn(FP,150),sY=new pn(RP,1.414),i9=new pn(Qw,null),qSt=new pn(rSe,1),KB=new pn(HTe,!1),Oge=new pn(VTe,!1),oNe=new pn(Ahe,1),cNe=(vU(),Uge),new pn(Qyt,cNe),BSt=!0,VSt=(dx(),L4),USt=L4,HSt=L4}function vo(){vo=U,PAe=new Ws("DIRECTION_PREPROCESSOR",0),IAe=new Ws("COMMENT_PREPROCESSOR",1),D6=new Ws("EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER",2),f1e=new Ws("INTERACTIVE_EXTERNAL_PORT_POSITIONER",3),eLe=new Ws("PARTITION_PREPROCESSOR",4),DK=new Ws("LABEL_DUMMY_INSERTER",5),zK=new Ws("SELF_LOOP_PREPROCESSOR",6),l4=new Ws("LAYER_CONSTRAINT_PREPROCESSOR",7),JAe=new Ws("PARTITION_MIDPROCESSOR",8),HAe=new Ws("HIGH_DEGREE_NODE_LAYER_PROCESSOR",9),XAe=new Ws("NODE_PROMOTION",10),u4=new Ws("LAYER_CONSTRAINT_POSTPROCESSOR",11),ZAe=new Ws("PARTITION_POSTPROCESSOR",12),$Ae=new Ws("HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR",13),tLe=new Ws("SEMI_INTERACTIVE_CROSSMIN_PROCESSOR",14),SAe=new Ws("BREAKING_POINT_INSERTER",15),PK=new Ws("LONG_EDGE_SPLITTER",16),d1e=new Ws("PORT_SIDE_PROCESSOR",17),LK=new Ws("INVERTED_PORT_PROCESSOR",18),RK=new Ws("PORT_LIST_SORTER",19),rLe=new Ws("SORT_BY_INPUT_ORDER_OF_MODEL",20),FK=new Ws("NORTH_SOUTH_PORT_PREPROCESSOR",21),_Ae=new Ws("BREAKING_POINT_PROCESSOR",22),QAe=new Ws(H3t,23),iLe=new Ws(V3t,24),jK=new Ws("SELF_LOOP_PORT_RESTORER",25),nLe=new Ws("SINGLE_EDGE_GRAPH_WRAPPER",26),MK=new Ws("IN_LAYER_CONSTRAINT_PROCESSOR",27),FAe=new Ws("END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR",28),WAe=new Ws("LABEL_AND_NODE_SIZE_PROCESSOR",29),KAe=new Ws("INNERMOST_NODE_MARGIN_CALCULATOR",30),qK=new Ws("SELF_LOOP_ROUTER",31),MAe=new Ws("COMMENT_NODE_MARGIN_CALCULATOR",32),AK=new Ws("END_LABEL_PREPROCESSOR",33),OK=new Ws("LABEL_DUMMY_SWITCHER",34),LAe=new Ws("CENTER_LABEL_MANAGEMENT_PROCESSOR",35),LT=new Ws("LABEL_SIDE_SELECTOR",36),UAe=new Ws("HYPEREDGE_DUMMY_MERGER",37),zAe=new Ws("HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR",38),YAe=new Ws("LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR",39),zL=new Ws("HIERARCHICAL_PORT_POSITION_PROCESSOR",40),OAe=new Ws("CONSTRAINTS_POSTPROCESSOR",41),DAe=new Ws("COMMENT_POSTPROCESSOR",42),GAe=new Ws("HYPERNODE_PROCESSOR",43),qAe=new Ws("HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER",44),NK=new Ws("LONG_EDGE_JOINER",45),$K=new Ws("SELF_LOOP_POSTPROCESSOR",46),AAe=new Ws("BREAKING_POINT_REMOVER",47),BK=new Ws("NORTH_SOUTH_PORT_POSTPROCESSOR",48),VAe=new Ws("HORIZONTAL_COMPACTOR",49),IK=new Ws("LABEL_DUMMY_REMOVER",50),RAe=new Ws("FINAL_SPLINE_BENDPOINTS_CALCULATOR",51),BAe=new Ws("END_LABEL_SORTER",52),gB=new Ws("REVERSED_EDGE_RESTORER",53),_K=new Ws("END_LABEL_POSTPROCESSOR",54),jAe=new Ws("HIERARCHICAL_NODE_RESIZER",55),NAe=new Ws("DIRECTION_POSTPROCESSOR",56)}function Yke(){Yke=U,iMe=(pN(),XK),r9t=new pn(VEe,iMe),p9t=new pn(UEe,(Hn(),!1)),lMe=(zH(),z1e),y9t=new pn(fG,lMe),P9t=new pn(GEe,!1),B9t=new pn(KEe,!0),Lxt=new pn(WEe,!1),vMe=(dN(),kde),Q9t=new pn(YEe,vMe),pt(1),skt=new pn(XEe,pt(7)),akt=new pn(QEe,!1),b9t=new pn(JEe,!1),rMe=(l2(),A1e),n9t=new pn(zhe,rMe),dMe=(p2(),gde),N9t=new pn(qP,dMe),hMe=(hf(),EB),S9t=new pn(ZEe,hMe),pt(-1),C9t=new pn(eTe,null),pt(-1),_9t=new pn(tTe,pt(-1)),pt(-1),A9t=new pn(qhe,pt(4)),pt(-1),M9t=new pn(Hhe,pt(2)),fMe=(Nf(),AW),O9t=new pn(Vhe,fMe),pt(0),I9t=new pn(Uhe,pt(0)),E9t=new pn(Ghe,pt(Ii)),nMe=(dA(),HL),t9t=new pn(pL,nMe),$xt=new pn(nTe,!1),Kxt=new pn(Khe,.1),Zxt=new pn(Whe,!1),Yxt=new pn(rTe,null),Xxt=new pn(iTe,null),pt(-1),Qxt=new pn(sTe,null),pt(-1),Jxt=new pn(aTe,pt(-1)),pt(0),zxt=new pn(oTe,pt(40)),tMe=(vE(),j1e),Uxt=new pn(Yhe,tMe),eMe=vB,qxt=new pn(dG,eMe),mMe=(OA(),rM),X9t=new pn(k6,mMe),z9t=new Ui(gG),gMe=(cN(),JK),F9t=new pn(Xhe,gMe),pMe=(WN(),ZK),j9t=new pn(Qhe,pMe),V9t=new pn(Jhe,.3),G9t=new Ui(Zhe),bMe=(By(),_W),K9t=new pn(efe,bMe),oMe=(LV(),Tde),c9t=new pn(cTe,oMe),cMe=(yA(),Sde),u9t=new pn(uTe,cMe),uMe=(SE(),aM),l9t=new pn(pG,uMe),f9t=new pn(bG,.2),a9t=new pn(tfe,2),tkt=new pn(lTe,null),rkt=new pn(hTe,10),nkt=new pn(fTe,10),ikt=new pn(dTe,20),pt(0),J9t=new pn(gTe,pt(0)),pt(0),Z9t=new pn(pTe,pt(0)),pt(0),ekt=new pn(bTe,pt(0)),Mxt=new pn(nfe,!1),XLe=(zE(),VL),Ixt=new pn(mTe,XLe),YLe=(JH(),S1e),Dxt=new pn(vTe,YLe),v9t=new pn(mG,!1),pt(0),m9t=new pn(rfe,pt(16)),pt(0),w9t=new pn(ife,pt(5)),xMe=(OV(),Lde),Skt=new pn(fp,xMe),okt=new pn(vG,10),lkt=new pn(wG,1),yMe=(pV(),YK),mkt=new pn(bL,yMe),dkt=new Ui(sfe),wMe=pt(1),pt(0),pkt=new pn(afe,wMe),kMe=(gV(),Ade),Mkt=new pn(yG,kMe),_kt=new Ui(xG),kkt=new pn(kG,!0),ykt=new pn(EG,2),Tkt=new pn(ofe,!0),aMe=(yU(),QK),s9t=new pn(wTe,aMe),sMe=(yx(),OT),i9t=new pn(yTe,sMe),ZLe=(Ed(),E2),jxt=new pn(TG,ZLe),Rxt=new pn(xTe,!1),Fxt=new pn(kTe,!1),QLe=(Km(),c4),Oxt=new pn(cfe,QLe),JLe=(EA(),pde),Bxt=new pn(ETe,JLe),Nxt=new pn(ufe,0),Pxt=new pn(lfe,0),k9t=L1e,x9t=mB,L9t=CW,D9t=CW,T9t=dde,Wxt=(rp(),A2),e9t=HL,Gxt=HL,Hxt=HL,Vxt=A2,q9t=iM,H9t=rM,R9t=rM,$9t=rM,U9t=wde,Y9t=iM,W9t=iM,h9t=(ip(),s9),d9t=s9,g9t=aM,o9t=JB,ckt=XT,ukt=k4,hkt=XT,fkt=k4,vkt=XT,wkt=k4,gkt=_1e,bkt=YK,Dkt=XT,Ikt=k4,Akt=XT,Lkt=k4,Ekt=k4,xkt=k4,Ckt=k4}function eOn(e,t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn,jn,ur,oi,ws,Vl,lc,Hh,f7,P2,L0,M0,_v,h9,rm,f9,qd,_g,S3,d9,d7,Hd,Av,yp,IAt,sBe,_3,YM,lpe,g9,XM,F4,QM,hpe,OAt;for(sBe=0,oi=t,lc=0,P2=oi.length;lc0&&(e.a[qd.p]=sBe++)}for(XM=0,ws=n,Hh=0,L0=ws.length;Hh0;){for(qd=(mr(d7.b>0),l(d7.a.Xb(d7.c=--d7.b),12)),d9=0,g=new G(qd.e);g.a0&&(qd.j==(Ct(),Qn)?(e.a[qd.p]=XM,++XM):(e.a[qd.p]=XM+M0+h9,++h9))}XM+=h9}for(S3=new Pr,V=new bd,ur=t,Vl=0,f7=ur.length;VlE.b&&(E.b=Hd)):qd.i.c==IAt&&(HdE.c&&(E.c=Hd));for(nE(J,0,J.length,null),g9=We(Vr,di,28,J.length,15,1),r=We(Vr,di,28,XM+1,15,1),fe=0;fe0;)St%2>0&&(a+=hpe[St+1]),St=(St-1)/2|0,++hpe[St];for(an=We(MEt,Rn,374,J.length*2,0,1),$e=0;$e0&&GO(Vl.f),at(fe,BNe)!=null&&(g=l(at(fe,BNe),347),S3=g.Tg(fe),F5(fe,b.Math.max(fe.g,S3.a),b.Math.max(fe.f,S3.b)));if(L0=l(at(t,_2),107),z=t.g-(L0.b+L0.c),B=t.f-(L0.d+L0.a),Hd.bh("Available Child Area: ("+z+"|"+B+")"),Hi(t,Z6,z/B),sdt(t,a,r.eh(f7)),l(at(t,i9),280)==dY&&(Uke(t),F5(t,L0.b+ze(Ge(at(t,t7)))+L0.c,L0.d+ze(Ge(at(t,e7)))+L0.a)),Hd.bh("Executed layout algorithm: "+ei(at(t,eC))+" on node "+t.k),l(at(t,i9),280)==L4){if(z<0||B<0)throw ue(new Vp("The size defined by the parent parallel node is too small for the space provided by the paddings of the child hierarchical node. "+t.k));for(P1(t,t7)||P1(t,e7)||Uke(t),J=ze(Ge(at(t,t7))),V=ze(Ge(at(t,e7))),Hd.bh("Desired Child Area: ("+J+"|"+V+")"),_v=z/J,h9=B/V,M0=b.Math.min(_v,b.Math.min(h9,ze(Ge(at(t,qSt))))),Hi(t,aY,M0),Hd.bh(t.k+" -- Local Scale Factor (X|Y): ("+_v+"|"+h9+")"),$e=l(at(t,UB),21),o=0,f=0,M0<_v&&($e.Hc((Ym(),EM))?o=(z/2-J*M0/2)/M0:$e.Hc(TM)&&(o=(z-J*M0)/M0)),M0'?":vn(L4t,e)?"'(?<' or '(? toIndex: ",fEe=", toIndex: ",dEe="Index: ",gEe=", Size: ",oT="org.eclipse.elk.alg.common",ii={50:1},Jwt="org.eclipse.elk.alg.common.compaction",Zwt="Scanline/EventHandler",gg="org.eclipse.elk.alg.common.compaction.oned",e3t="CNode belongs to another CGroup.",t3t="ISpacingsHandler/1",phe="The ",bhe=" instance has been finished already.",n3t="The direction ",r3t=" is not supported by the CGraph instance.",i3t="OneDimensionalCompactor",s3t="OneDimensionalCompactor/lambda$0$Type",a3t="Quadruplet",o3t="ScanlineConstraintCalculator",c3t="ScanlineConstraintCalculator/ConstraintsScanlineHandler",u3t="ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type",l3t="ScanlineConstraintCalculator/Timestamp",h3t="ScanlineConstraintCalculator/lambda$0$Type",Ld={178:1,46:1},mhe="org.eclipse.elk.alg.common.compaction.options",Nc="org.eclipse.elk.core.data",pEe="org.eclipse.elk.polyomino.traversalStrategy",bEe="org.eclipse.elk.polyomino.lowLevelSort",mEe="org.eclipse.elk.polyomino.highLevelSort",vEe="org.eclipse.elk.polyomino.fill",Pf={134:1},vhe="polyomino",oL="org.eclipse.elk.alg.common.networksimplex",pg={183:1,3:1,4:1},f3t="org.eclipse.elk.alg.common.nodespacing",ev="org.eclipse.elk.alg.common.nodespacing.cellsystem",cT="CENTER",d3t={217:1,336:1},wEe={3:1,4:1,5:1,603:1},Mx="LEFT",Dx="RIGHT",yEe="Vertical alignment cannot be null",xEe="BOTTOM",tG="org.eclipse.elk.alg.common.nodespacing.internal",cL="UNDEFINED",H1=.01,DP="org.eclipse.elk.alg.common.nodespacing.internal.algorithm",g3t="LabelPlacer/lambda$0$Type",p3t="LabelPlacer/lambda$1$Type",b3t="portRatioOrPosition",uT="org.eclipse.elk.alg.common.overlaps",whe="DOWN",Md="org.eclipse.elk.alg.common.polyomino",nG="NORTH",yhe="EAST",xhe="SOUTH",khe="WEST",rG="org.eclipse.elk.alg.common.polyomino.structures",kEe="Direction",Ehe="Grid is only of size ",The=". Requested point (",Che=") is out of bounds.",iG=" Given center based coordinates were (",IP="org.eclipse.elk.graph.properties",m3t="IPropertyHolder",EEe={3:1,96:1,137:1},Ix="org.eclipse.elk.alg.common.spore",v3t="org.eclipse.elk.alg.common.utils",tv={205:1},v6="org.eclipse.elk.core",w3t="Connected Components Compaction",y3t="org.eclipse.elk.alg.disco",sG="org.eclipse.elk.alg.disco.graph",She="org.eclipse.elk.alg.disco.options",TEe="CompactionStrategy",CEe="org.eclipse.elk.disco.componentCompaction.strategy",SEe="org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm",_Ee="org.eclipse.elk.disco.debug.discoGraph",AEe="org.eclipse.elk.disco.debug.discoPolys",x3t="componentCompaction",nv="org.eclipse.elk.disco",_he="org.eclipse.elk.spacing.componentComponent",Ahe="org.eclipse.elk.edge.thickness",Ox="org.eclipse.elk.aspectRatio",Xw="org.eclipse.elk.padding",w6="org.eclipse.elk.alg.disco.transform",Lhe=1.5707963267948966,y6=17976931348623157e292,Qy={3:1,4:1,5:1,198:1},k3t={3:1,6:1,4:1,5:1,100:1,115:1},Mhe="org.eclipse.elk.alg.force",LEe="ComponentsProcessor",E3t="ComponentsProcessor/1",MEe="ElkGraphImporter/lambda$0$Type",OP="org.eclipse.elk.alg.force.graph",T3t="Component Layout",DEe="org.eclipse.elk.alg.force.model",aG="org.eclipse.elk.force.model",IEe="org.eclipse.elk.force.iterations",OEe="org.eclipse.elk.force.repulsivePower",Dhe="org.eclipse.elk.force.temperature",Dd=.001,Ihe="org.eclipse.elk.force.repulsion",uL="org.eclipse.elk.alg.force.options",lT=1.600000023841858,Yu="org.eclipse.elk.force",NP="org.eclipse.elk.priority",Jy="org.eclipse.elk.spacing.nodeNode",Ohe="org.eclipse.elk.spacing.edgeLabel",oG="org.eclipse.elk.randomSeed",lL="org.eclipse.elk.separateConnectedComponents",hL="org.eclipse.elk.interactive",Nhe="org.eclipse.elk.portConstraints",cG="org.eclipse.elk.edgeLabels.inline",fL="org.eclipse.elk.omitNodeMicroLayout",hT="org.eclipse.elk.nodeSize.fixedGraphSize",Nx="org.eclipse.elk.nodeSize.options",x6="org.eclipse.elk.nodeSize.constraints",fT="org.eclipse.elk.nodeLabels.placement",dT="org.eclipse.elk.portLabels.placement",PP="org.eclipse.elk.topdownLayout",BP="org.eclipse.elk.topdown.scaleFactor",FP="org.eclipse.elk.topdown.hierarchicalNodeWidth",RP="org.eclipse.elk.topdown.hierarchicalNodeAspectRatio",Qw="org.eclipse.elk.topdown.nodeType",NEe="origin",C3t="random",S3t="boundingBox.upLeft",_3t="boundingBox.lowRight",PEe="org.eclipse.elk.stress.fixed",BEe="org.eclipse.elk.stress.desiredEdgeLength",FEe="org.eclipse.elk.stress.dimension",REe="org.eclipse.elk.stress.epsilon",jEe="org.eclipse.elk.stress.iterationLimit",Mb="org.eclipse.elk.stress",A3t="ELK Stress",Px="org.eclipse.elk.nodeSize.minimum",uG="org.eclipse.elk.alg.force.stress",L3t="Layered layout",Bx="org.eclipse.elk.alg.layered",jP="org.eclipse.elk.alg.layered.compaction.components",dL="org.eclipse.elk.alg.layered.compaction.oned",lG="org.eclipse.elk.alg.layered.compaction.oned.algs",rv="org.eclipse.elk.alg.layered.compaction.recthull",V1="org.eclipse.elk.alg.layered.components",Id="NONE",$Ee="MODEL_ORDER",au={3:1,6:1,4:1,9:1,5:1,126:1},M3t={3:1,6:1,4:1,5:1,150:1,100:1,115:1},hG="org.eclipse.elk.alg.layered.compound",ts={47:1},Cu="org.eclipse.elk.alg.layered.graph",Phe=" -> ",D3t="Not supported by LGraph",zEe="Port side is undefined",Bhe={3:1,6:1,4:1,5:1,483:1,150:1,100:1,115:1},m2={3:1,6:1,4:1,5:1,150:1,199:1,210:1,100:1,115:1},I3t={3:1,6:1,4:1,5:1,150:1,2042:1,210:1,100:1,115:1},O3t=`([{"' \r +`,N3t=`)]}"' \r +`,P3t="The given string contains parts that cannot be parsed as numbers.",$P="org.eclipse.elk.core.math",B3t={3:1,4:1,140:1,214:1,423:1},F3t={3:1,4:1,107:1,214:1,423:1},v2="org.eclipse.elk.alg.layered.graph.transform",R3t="ElkGraphImporter",j3t="ElkGraphImporter/lambda$1$Type",$3t="ElkGraphImporter/lambda$2$Type",z3t="ElkGraphImporter/lambda$4$Type",rr="org.eclipse.elk.alg.layered.intermediate",q3t="Node margin calculation",H3t="ONE_SIDED_GREEDY_SWITCH",V3t="TWO_SIDED_GREEDY_SWITCH",Fhe="No implementation is available for the layout processor ",Rhe="IntermediateProcessorStrategy",jhe="Node '",U3t="FIRST_SEPARATE",G3t="LAST_SEPARATE",K3t="Odd port side processing",aa="org.eclipse.elk.alg.layered.intermediate.compaction",gL="org.eclipse.elk.alg.layered.intermediate.greedyswitch",bg="org.eclipse.elk.alg.layered.p3order.counting",zP={230:1},Fx="org.eclipse.elk.alg.layered.intermediate.loops",Bh="org.eclipse.elk.alg.layered.intermediate.loops.ordering",Db="org.eclipse.elk.alg.layered.intermediate.loops.routing",qEe="org.eclipse.elk.alg.layered.intermediate.preserveorder",Od="org.eclipse.elk.alg.layered.intermediate.wrapping",ou="org.eclipse.elk.alg.layered.options",$he="INTERACTIVE",HEe="GREEDY",W3t="DEPTH_FIRST",Y3t="EDGE_LENGTH",X3t="SELF_LOOPS",Q3t="firstTryWithInitialOrder",VEe="org.eclipse.elk.layered.directionCongruency",UEe="org.eclipse.elk.layered.feedbackEdges",fG="org.eclipse.elk.layered.interactiveReferencePoint",GEe="org.eclipse.elk.layered.mergeEdges",KEe="org.eclipse.elk.layered.mergeHierarchyEdges",WEe="org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides",YEe="org.eclipse.elk.layered.portSortingStrategy",XEe="org.eclipse.elk.layered.thoroughness",QEe="org.eclipse.elk.layered.unnecessaryBendpoints",JEe="org.eclipse.elk.layered.generatePositionAndLayerIds",zhe="org.eclipse.elk.layered.cycleBreaking.strategy",qP="org.eclipse.elk.layered.layering.strategy",ZEe="org.eclipse.elk.layered.layering.layerConstraint",eTe="org.eclipse.elk.layered.layering.layerChoiceConstraint",tTe="org.eclipse.elk.layered.layering.layerId",qhe="org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth",Hhe="org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor",Vhe="org.eclipse.elk.layered.layering.nodePromotion.strategy",Uhe="org.eclipse.elk.layered.layering.nodePromotion.maxIterations",Ghe="org.eclipse.elk.layered.layering.coffmanGraham.layerBound",pL="org.eclipse.elk.layered.crossingMinimization.strategy",nTe="org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder",Khe="org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness",Whe="org.eclipse.elk.layered.crossingMinimization.semiInteractive",rTe="org.eclipse.elk.layered.crossingMinimization.inLayerPredOf",iTe="org.eclipse.elk.layered.crossingMinimization.inLayerSuccOf",sTe="org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint",aTe="org.eclipse.elk.layered.crossingMinimization.positionId",oTe="org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold",Yhe="org.eclipse.elk.layered.crossingMinimization.greedySwitch.type",dG="org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type",k6="org.eclipse.elk.layered.nodePlacement.strategy",gG="org.eclipse.elk.layered.nodePlacement.favorStraightEdges",Xhe="org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening",Qhe="org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment",Jhe="org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening",Zhe="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility",efe="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default",cTe="org.eclipse.elk.layered.edgeRouting.selfLoopDistribution",uTe="org.eclipse.elk.layered.edgeRouting.selfLoopOrdering",pG="org.eclipse.elk.layered.edgeRouting.splines.mode",bG="org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor",tfe="org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth",lTe="org.eclipse.elk.layered.spacing.baseValue",hTe="org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers",fTe="org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers",dTe="org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers",gTe="org.eclipse.elk.layered.priority.direction",pTe="org.eclipse.elk.layered.priority.shortness",bTe="org.eclipse.elk.layered.priority.straightness",nfe="org.eclipse.elk.layered.compaction.connectedComponents",mTe="org.eclipse.elk.layered.compaction.postCompaction.strategy",vTe="org.eclipse.elk.layered.compaction.postCompaction.constraints",mG="org.eclipse.elk.layered.highDegreeNodes.treatment",rfe="org.eclipse.elk.layered.highDegreeNodes.threshold",ife="org.eclipse.elk.layered.highDegreeNodes.treeHeight",fp="org.eclipse.elk.layered.wrapping.strategy",vG="org.eclipse.elk.layered.wrapping.additionalEdgeSpacing",wG="org.eclipse.elk.layered.wrapping.correctionFactor",bL="org.eclipse.elk.layered.wrapping.cutting.strategy",sfe="org.eclipse.elk.layered.wrapping.cutting.cuts",afe="org.eclipse.elk.layered.wrapping.cutting.msd.freedom",yG="org.eclipse.elk.layered.wrapping.validify.strategy",xG="org.eclipse.elk.layered.wrapping.validify.forbiddenIndices",kG="org.eclipse.elk.layered.wrapping.multiEdge.improveCuts",EG="org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty",ofe="org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges",wTe="org.eclipse.elk.layered.edgeLabels.sideSelection",yTe="org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy",TG="org.eclipse.elk.layered.considerModelOrder.strategy",xTe="org.eclipse.elk.layered.considerModelOrder.portModelOrder",kTe="org.eclipse.elk.layered.considerModelOrder.noModelOrder",cfe="org.eclipse.elk.layered.considerModelOrder.components",ETe="org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy",ufe="org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence",lfe="org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence",hfe="layering",J3t="layering.minWidth",Z3t="layering.nodePromotion",gT="crossingMinimization",CG="org.eclipse.elk.hierarchyHandling",eyt="crossingMinimization.greedySwitch",tyt="nodePlacement",nyt="nodePlacement.bk",ryt="edgeRouting",HP="org.eclipse.elk.edgeRouting",U1="spacing",TTe="priority",CTe="compaction",iyt="compaction.postCompaction",syt="Specifies whether and how post-process compaction is applied.",STe="highDegreeNodes",_Te="wrapping",ayt="wrapping.cutting",oyt="wrapping.validify",ATe="wrapping.multiEdge",ffe="edgeLabels",mL="considerModelOrder",LTe="org.eclipse.elk.spacing.commentComment",MTe="org.eclipse.elk.spacing.commentNode",DTe="org.eclipse.elk.spacing.edgeEdge",dfe="org.eclipse.elk.spacing.edgeNode",ITe="org.eclipse.elk.spacing.labelLabel",OTe="org.eclipse.elk.spacing.labelPortHorizontal",NTe="org.eclipse.elk.spacing.labelPortVertical",PTe="org.eclipse.elk.spacing.labelNode",BTe="org.eclipse.elk.spacing.nodeSelfLoop",FTe="org.eclipse.elk.spacing.portPort",RTe="org.eclipse.elk.spacing.individual",jTe="org.eclipse.elk.port.borderOffset",$Te="org.eclipse.elk.noLayout",zTe="org.eclipse.elk.port.side",VP="org.eclipse.elk.debugMode",qTe="org.eclipse.elk.alignment",HTe="org.eclipse.elk.insideSelfLoops.activate",VTe="org.eclipse.elk.insideSelfLoops.yo",gfe="org.eclipse.elk.direction",UTe="org.eclipse.elk.nodeLabels.padding",GTe="org.eclipse.elk.portLabels.nextToPortIfPossible",KTe="org.eclipse.elk.portLabels.treatAsGroup",WTe="org.eclipse.elk.portAlignment.default",YTe="org.eclipse.elk.portAlignment.north",XTe="org.eclipse.elk.portAlignment.south",QTe="org.eclipse.elk.portAlignment.west",JTe="org.eclipse.elk.portAlignment.east",SG="org.eclipse.elk.contentAlignment",ZTe="org.eclipse.elk.junctionPoints",eCe="org.eclipse.elk.edgeLabels.placement",tCe="org.eclipse.elk.port.index",nCe="org.eclipse.elk.commentBox",rCe="org.eclipse.elk.hypernode",iCe="org.eclipse.elk.port.anchor",pfe="org.eclipse.elk.partitioning.activate",bfe="org.eclipse.elk.partitioning.partition",_G="org.eclipse.elk.position",sCe="org.eclipse.elk.margins",aCe="org.eclipse.elk.spacing.portsSurrounding",AG="org.eclipse.elk.interactiveLayout",Uc="org.eclipse.elk.core.util",oCe={3:1,4:1,5:1,601:1},cyt="NETWORK_SIMPLEX",cCe="SIMPLE",Uo={106:1,47:1},LG="org.eclipse.elk.alg.layered.p1cycles",dp="org.eclipse.elk.alg.layered.p2layers",uCe={413:1,230:1},uyt={846:1,3:1,4:1},Cl="org.eclipse.elk.alg.layered.p3order",Go="org.eclipse.elk.alg.layered.p4nodes",lyt={3:1,4:1,5:1,854:1},Nd=1e-5,Ib="org.eclipse.elk.alg.layered.p4nodes.bk",mfe="org.eclipse.elk.alg.layered.p5edges",i1="org.eclipse.elk.alg.layered.p5edges.orthogonal",vfe="org.eclipse.elk.alg.layered.p5edges.orthogonal.direction",wfe=1e-6,Zy="org.eclipse.elk.alg.layered.p5edges.splines",yfe=.09999999999999998,MG=1e-8,hyt=4.71238898038469,lCe=3.141592653589793,gp="org.eclipse.elk.alg.mrtree",xfe=.10000000149011612,DG="SUPER_ROOT",vL="org.eclipse.elk.alg.mrtree.graph",hCe=-17976931348623157e292,Su="org.eclipse.elk.alg.mrtree.intermediate",fyt="Processor compute fanout",IG={3:1,6:1,4:1,5:1,534:1,100:1,115:1},dyt="Set neighbors in level",UP="org.eclipse.elk.alg.mrtree.options",gyt="DESCENDANTS",fCe="org.eclipse.elk.mrtree.compaction",dCe="org.eclipse.elk.mrtree.edgeEndTextureLength",gCe="org.eclipse.elk.mrtree.treeLevel",pCe="org.eclipse.elk.mrtree.positionConstraint",bCe="org.eclipse.elk.mrtree.weighting",mCe="org.eclipse.elk.mrtree.edgeRoutingMode",vCe="org.eclipse.elk.mrtree.searchOrder",pyt="Position Constraint",Xu="org.eclipse.elk.mrtree",byt="org.eclipse.elk.tree",myt="Processor arrange level",pT="org.eclipse.elk.alg.mrtree.p2order",vh="org.eclipse.elk.alg.mrtree.p4route",wCe="org.eclipse.elk.alg.radial",iv=6.283185307179586,yCe="Before",xCe=5e-324,OG="After",kCe="org.eclipse.elk.alg.radial.intermediate",vyt="COMPACTION",kfe="org.eclipse.elk.alg.radial.intermediate.compaction",wyt={3:1,4:1,5:1,100:1},ECe="org.eclipse.elk.alg.radial.intermediate.optimization",Efe="No implementation is available for the layout option ",wL="org.eclipse.elk.alg.radial.options",TCe="org.eclipse.elk.radial.centerOnRoot",CCe="org.eclipse.elk.radial.orderId",SCe="org.eclipse.elk.radial.radius",NG="org.eclipse.elk.radial.rotate",Tfe="org.eclipse.elk.radial.compactor",Cfe="org.eclipse.elk.radial.compactionStepSize",_Ce="org.eclipse.elk.radial.sorter",ACe="org.eclipse.elk.radial.wedgeCriteria",LCe="org.eclipse.elk.radial.optimizationCriteria",Sfe="org.eclipse.elk.radial.rotation.targetAngle",_fe="org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace",MCe="org.eclipse.elk.radial.rotation.outgoingEdgeAngles",yyt="Compaction",DCe="rotation",gf="org.eclipse.elk.radial",xyt="org.eclipse.elk.alg.radial.p1position.wedge",ICe="org.eclipse.elk.alg.radial.sorting",kyt=5.497787143782138,Eyt=3.9269908169872414,Tyt=2.356194490192345,Cyt="org.eclipse.elk.alg.rectpacking",PG="org.eclipse.elk.alg.rectpacking.intermediate",Afe="org.eclipse.elk.alg.rectpacking.options",OCe="org.eclipse.elk.rectpacking.trybox",NCe="org.eclipse.elk.rectpacking.currentPosition",PCe="org.eclipse.elk.rectpacking.desiredPosition",BCe="org.eclipse.elk.rectpacking.inNewRow",FCe="org.eclipse.elk.rectpacking.widthApproximation.strategy",RCe="org.eclipse.elk.rectpacking.widthApproximation.targetWidth",jCe="org.eclipse.elk.rectpacking.widthApproximation.optimizationGoal",$Ce="org.eclipse.elk.rectpacking.widthApproximation.lastPlaceShift",zCe="org.eclipse.elk.rectpacking.packing.strategy",qCe="org.eclipse.elk.rectpacking.packing.compaction.rowHeightReevaluation",HCe="org.eclipse.elk.rectpacking.packing.compaction.iterations",VCe="org.eclipse.elk.rectpacking.whiteSpaceElimination.strategy",Lfe="widthApproximation",Syt="Compaction Strategy",_yt="packing.compaction",th="org.eclipse.elk.rectpacking",bT="org.eclipse.elk.alg.rectpacking.p1widthapproximation",BG="org.eclipse.elk.alg.rectpacking.p2packing",Ayt="No Compaction",UCe="org.eclipse.elk.alg.rectpacking.p3whitespaceelimination",GP="org.eclipse.elk.alg.rectpacking.util",FG="No implementation available for ",e4="org.eclipse.elk.alg.spore",t4="org.eclipse.elk.alg.spore.options",Jw="org.eclipse.elk.sporeCompaction",Mfe="org.eclipse.elk.underlyingLayoutAlgorithm",GCe="org.eclipse.elk.processingOrder.treeConstruction",KCe="org.eclipse.elk.processingOrder.spanningTreeCostFunction",Dfe="org.eclipse.elk.processingOrder.preferredRoot",Ife="org.eclipse.elk.processingOrder.rootSelection",Ofe="org.eclipse.elk.structure.structureExtractionStrategy",WCe="org.eclipse.elk.compaction.compactionStrategy",YCe="org.eclipse.elk.compaction.orthogonal",XCe="org.eclipse.elk.overlapRemoval.maxIterations",QCe="org.eclipse.elk.overlapRemoval.runScanline",Nfe="processingOrder",Lyt="overlapRemoval",mT="org.eclipse.elk.sporeOverlap",Myt="org.eclipse.elk.alg.spore.p1structure",Pfe="org.eclipse.elk.alg.spore.p2processingorder",Bfe="org.eclipse.elk.alg.spore.p3execution",Dyt="Topdown Layout",Iyt="Invalid index: ",vT="org.eclipse.elk.core.alg",E6={341:1},n4={295:1},Oyt="Make sure its type is registered with the ",JCe=" utility class.",wT="true",Ffe="false",Nyt="Couldn't clone property '",Zw=.05,nh="org.eclipse.elk.core.options",Pyt=1.2999999523162842,e3="org.eclipse.elk.box",ZCe="org.eclipse.elk.expandNodes",eSe="org.eclipse.elk.box.packingMode",Byt="org.eclipse.elk.algorithm",Fyt="org.eclipse.elk.resolvedAlgorithm",tSe="org.eclipse.elk.bendPoints",sOn="org.eclipse.elk.labelManager",Ryt="org.eclipse.elk.scaleFactor",jyt="org.eclipse.elk.childAreaWidth",$yt="org.eclipse.elk.childAreaHeight",zyt="org.eclipse.elk.animate",qyt="org.eclipse.elk.animTimeFactor",Hyt="org.eclipse.elk.layoutAncestors",Vyt="org.eclipse.elk.maxAnimTime",Uyt="org.eclipse.elk.minAnimTime",Gyt="org.eclipse.elk.progressBar",Kyt="org.eclipse.elk.validateGraph",Wyt="org.eclipse.elk.validateOptions",Yyt="org.eclipse.elk.zoomToFit",aOn="org.eclipse.elk.font.name",Xyt="org.eclipse.elk.font.size",nSe="org.eclipse.elk.topdown.sizeApproximator",rSe="org.eclipse.elk.topdown.scaleCap",Qyt="org.eclipse.elk.edge.type",Jyt="partitioning",Zyt="nodeLabels",RG="portAlignment",Rfe="nodeSize",jfe="port",iSe="portLabels",KP="topdown",e4t="insideSelfLoops",yL="org.eclipse.elk.fixed",jG="org.eclipse.elk.random",sSe={3:1,34:1,22:1,347:1},t4t="port must have a parent node to calculate the port side",n4t="The edge needs to have exactly one edge section. Found: ",xL="org.eclipse.elk.core.util.adapters",pf="org.eclipse.emf.ecore",T6="org.eclipse.elk.graph",r4t="EMapPropertyHolder",i4t="ElkBendPoint",s4t="ElkGraphElement",a4t="ElkConnectableShape",aSe="ElkEdge",o4t="ElkEdgeSection",c4t="EModelElement",u4t="ENamedElement",oSe="ElkLabel",cSe="ElkNode",uSe="ElkPort",l4t={94:1,93:1},Rx="org.eclipse.emf.common.notify.impl",Ob="The feature '",kL="' is not a valid changeable feature",h4t="Expecting null",$fe="' is not a valid feature",f4t="The feature ID",d4t=" is not a valid feature ID",eu=32768,g4t={110:1,94:1,93:1,58:1,54:1,99:1},Gn="org.eclipse.emf.ecore.impl",sv="org.eclipse.elk.graph.impl",EL="Recursive containment not allowed for ",yT="The datatype '",t3="' is not a valid classifier",zfe="The value '",C6={195:1,3:1,4:1},qfe="The class '",xT="http://www.eclipse.org/elk/ElkGraph",lSe="property",TL="value",Hfe="source",p4t="properties",b4t="identifier",Vfe="height",Ufe="width",Gfe="parent",Kfe="text",Wfe="children",m4t="hierarchical",hSe="sources",Yfe="targets",fSe="sections",$G="bendPoints",dSe="outgoingShape",gSe="incomingShape",pSe="outgoingSections",bSe="incomingSections",So="org.eclipse.emf.common.util",mSe="Severe implementation error in the Json to ElkGraph importer.",Pd="id",no="org.eclipse.elk.graph.json",vSe="Unhandled parameter types: ",v4t="startPoint",w4t="An edge must have at least one source and one target (edge id: '",kT="').",y4t="Referenced edge section does not exist: ",x4t=" (edge id: '",wSe="target",k4t="sourcePoint",E4t="targetPoint",zG="group",_i="name",T4t="connectableShape cannot be null",C4t="edge cannot be null",Xfe="Passed edge is not 'simple'.",qG="org.eclipse.elk.graph.util",WP="The 'no duplicates' constraint is violated",Qfe="targetIndex=",av=", size=",Jfe="sourceIndex=",Bd={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1},Zfe={3:1,4:1,20:1,31:1,56:1,16:1,51:1,15:1,59:1,70:1,66:1,61:1,596:1},HG="logging",S4t="measureExecutionTime",_4t="parser.parse.1",A4t="parser.parse.2",VG="parser.next.1",e0e="parser.next.2",L4t="parser.next.3",M4t="parser.next.4",ov="parser.factor.1",ySe="parser.factor.2",D4t="parser.factor.3",I4t="parser.factor.4",O4t="parser.factor.5",N4t="parser.factor.6",P4t="parser.atom.1",B4t="parser.atom.2",F4t="parser.atom.3",xSe="parser.atom.4",t0e="parser.atom.5",kSe="parser.cc.1",UG="parser.cc.2",R4t="parser.cc.3",j4t="parser.cc.5",ESe="parser.cc.6",TSe="parser.cc.7",n0e="parser.cc.8",$4t="parser.ope.1",z4t="parser.ope.2",q4t="parser.ope.3",w2="parser.descape.1",H4t="parser.descape.2",V4t="parser.descape.3",U4t="parser.descape.4",G4t="parser.descape.5",bf="parser.process.1",K4t="parser.quantifier.1",W4t="parser.quantifier.2",Y4t="parser.quantifier.3",X4t="parser.quantifier.4",CSe="parser.quantifier.5",Q4t="org.eclipse.emf.common.notify",SSe={424:1,686:1},J4t={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1},YP={378:1,152:1},CL="index=",r0e={3:1,4:1,5:1,129:1},Z4t={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,61:1},_Se={3:1,6:1,4:1,5:1,198:1},e5t={3:1,4:1,5:1,173:1,379:1},t5t=";/?:@&=+$,",n5t="invalid authority: ",r5t="EAnnotation",i5t="ETypedElement",s5t="EStructuralFeature",a5t="EAttribute",o5t="EClassifier",c5t="EEnumLiteral",u5t="EGenericType",l5t="EOperation",h5t="EParameter",f5t="EReference",d5t="ETypeParameter",us="org.eclipse.emf.ecore.util",i0e={79:1},ASe={3:1,20:1,16:1,15:1,61:1,597:1,79:1,71:1,97:1},g5t="org.eclipse.emf.ecore.util.FeatureMap$Entry",Sl=8192,r4=2048,SL="byte",GG="char",_L="double",AL="float",LL="int",ML="long",DL="short",p5t="java.lang.Object",S6={3:1,4:1,5:1,254:1},LSe={3:1,4:1,5:1,688:1},b5t={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,71:1},kc={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,71:1,97:1},XP="mixed",li="http:///org/eclipse/emf/ecore/util/ExtendedMetaData",Bf="kind",m5t={3:1,4:1,5:1,689:1},MSe={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1,79:1,71:1,97:1},KG={20:1,31:1,56:1,16:1,15:1,61:1,71:1},WG={51:1,128:1,287:1},YG={76:1,343:1},XG="The value of type '",QG="' must be of type '",_6=1352,Ff="http://www.eclipse.org/emf/2002/Ecore",JG=-32768,n3="constraints",ho="baseType",v5t="getEStructuralFeature",w5t="getFeatureID",IL="feature",y5t="getOperationID",DSe="operation",x5t="defaultValue",k5t="eTypeParameters",E5t="isInstance",T5t="getEEnumLiteral",C5t="eContainingClass",yi={57:1},S5t={3:1,4:1,5:1,124:1},_5t="org.eclipse.emf.ecore.resource",A5t={94:1,93:1,599:1,2034:1},s0e="org.eclipse.emf.ecore.resource.impl",ISe="unspecified",QP="simple",ZG="attribute",L5t="attributeWildcard",eK="element",a0e="elementWildcard",s1="collapse",o0e="itemType",tK="namespace",JP="##targetNamespace",Rf="whiteSpace",OSe="wildcards",cv="http://www.eclipse.org/emf/2003/XMLType",c0e="##any",ET="uninitialized",ZP="The multiplicity constraint is violated",nK="org.eclipse.emf.ecore.xml.type",M5t="ProcessingInstruction",D5t="SimpleAnyType",I5t="XMLTypeDocumentRoot",ea="org.eclipse.emf.ecore.xml.type.impl",eB="INF",O5t="processing",N5t="ENTITIES_._base",NSe="minLength",PSe="ENTITY",rK="NCName",P5t="IDREFS_._base",BSe="integer",u0e="token",l0e="pattern",B5t="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",FSe="\\i\\c*",F5t="[\\i-[:]][\\c-[:]]*",R5t="nonPositiveInteger",tB="maxInclusive",RSe="NMTOKEN",j5t="NMTOKENS_._base",jSe="nonNegativeInteger",nB="minInclusive",$5t="normalizedString",z5t="unsignedByte",q5t="unsignedInt",H5t="18446744073709551615",V5t="unsignedShort",U5t="processingInstruction",y2="org.eclipse.emf.ecore.xml.type.internal",TT=1114111,G5t="Internal Error: shorthands: \\u",OL="xml:isDigit",h0e="xml:isWord",f0e="xml:isSpace",d0e="xml:isNameChar",g0e="xml:isInitialNameChar",K5t="09٠٩۰۹०९০৯੦੯૦૯୦୯௧௯౦౯೦೯൦൯๐๙໐໙༠༩",W5t="AZazÀÖØöøıĴľŁňŊžƀǃǍǰǴǵǺȗɐʨʻˁΆΆΈΊΌΌΎΡΣώϐϖϚϚϜϜϞϞϠϠϢϳЁЌЎяёќўҁҐӄӇӈӋӌӐӫӮӵӸӹԱՖՙՙաֆאתװײءغفيٱڷںھۀێېۓەەۥۦअहऽऽक़ॡঅঌএঐওনপরললশহড়ঢ়য়ৡৰৱਅਊਏਐਓਨਪਰਲਲ਼ਵਸ਼ਸਹਖ਼ੜਫ਼ਫ਼ੲੴઅઋઍઍએઑઓનપરલળવહઽઽૠૠଅଌଏଐଓନପରଲଳଶହଽଽଡ଼ଢ଼ୟୡஅஊஎஐஒகஙசஜஜஞடணதநபமவஷஹఅఌఎఐఒనపళవహౠౡಅಌಎಐಒನಪಳವಹೞೞೠೡഅഌഎഐഒനപഹൠൡกฮะะาำเๅກຂຄຄງຈຊຊຍຍດທນຟມຣລລວວສຫອຮະະາຳຽຽເໄཀཇཉཀྵႠჅაჶᄀᄀᄂᄃᄅᄇᄉᄉᄋᄌᄎᄒᄼᄼᄾᄾᅀᅀᅌᅌᅎᅎᅐᅐᅔᅕᅙᅙᅟᅡᅣᅣᅥᅥᅧᅧᅩᅩᅭᅮᅲᅳᅵᅵᆞᆞᆨᆨᆫᆫᆮᆯᆷᆸᆺᆺᆼᇂᇫᇫᇰᇰᇹᇹḀẛẠỹἀἕἘἝἠὅὈὍὐὗὙὙὛὛὝὝὟώᾀᾴᾶᾼιιῂῄῆῌῐΐῖΊῠῬῲῴῶῼΩΩKÅ℮℮ↀↂ〇〇〡〩ぁゔァヺㄅㄬ一龥가힣",Y5t="Private Use",p0e="ASSIGNED",b0e="\0€ÿĀſƀɏɐʯʰ˿̀ͯͰϿЀӿ԰֏֐׿؀ۿ܀ݏހ޿ऀॿঀ৿਀੿઀૿଀୿஀௿ఀ౿ಀ೿ഀൿ඀෿฀๿຀໿ༀ࿿က႟Ⴀჿᄀᇿሀ፿Ꭰ᏿᐀ᙿ ᚟ᚠ᛿ក៿᠀᢯Ḁỿἀ῿ ⁰₟₠⃏⃐⃿℀⅏⅐↏←⇿∀⋿⌀⏿␀␿⑀⑟①⓿─╿▀▟■◿☀⛿✀➿⠀⣿⺀⻿⼀⿟⿰⿿ 〿぀ゟ゠ヿ㄀ㄯ㄰㆏㆐㆟ㆠㆿ㈀㋿㌀㏿㐀䶵一鿿ꀀ꒏꒐꓏가힣豈﫿ffﭏﭐ﷿︠︯︰﹏﹐﹯ﹰ﻾\uFEFF\uFEFF＀￯",$Se="UNASSIGNED",CT={3:1,122:1},X5t="org.eclipse.emf.ecore.xml.type.util",iK={3:1,4:1,5:1,381:1},zSe="org.eclipse.xtext.xbase.lib",Q5t="Cannot add elements to a Range",J5t="Cannot set elements in a Range",Z5t="Cannot remove elements from a Range",e6t="user.agent",h,sK,m0e;b.goog=b.goog||{},b.goog.global=b.goog.global||b,sK={},D(1,null,{},T),h.Fb=function(t){return Jtt(this,t)},h.Gb=function(){return this.Rm},h.Hb=function(){return fw(this)},h.Ib=function(){var t;return _m(bh(this))+"@"+(t=es(this)>>>0,t.toString(16))},h.equals=function(e){return this.Fb(e)},h.hashCode=function(){return this.Hb()},h.toString=function(){return this.Ib()};var t6t,n6t,r6t;D(297,1,{297:1,2124:1},B7e),h.ve=function(t){var n;return n=new B7e,n.i=4,t>1?n.c=yot(this,t-1):n.c=this,n},h.we=function(){return Gg(this),this.b},h.xe=function(){return _m(this)},h.ye=function(){return Gg(this),this.k},h.ze=function(){return(this.i&4)!=0},h.Ae=function(){return(this.i&1)!=0},h.Ib=function(){return K6e(this)},h.i=0;var wa=I(Vc,"Object",1),qSe=I(Vc,"Class",297);D(2096,1,yP),I(xP,"Optional",2096),D(1191,2096,yP,_),h.Fb=function(t){return t===this},h.Hb=function(){return 2040732332},h.Ib=function(){return"Optional.absent()"},h.Jb=function(t){return Xr(t),o_(),v0e};var v0e;I(xP,"Absent",1191),D(636,1,{},Zie),I(xP,"Joiner",636);var oOn=ks(xP,"Predicate");D(589,1,{178:1,589:1,3:1,46:1},gz),h.Mb=function(t){return y0t(this,t)},h.Lb=function(t){return y0t(this,t)},h.Fb=function(t){var n;return De(t,589)?(n=l(t,589),O9e(this.a,n.a)):!1},h.Hb=function(){return q7e(this.a)+306654252},h.Ib=function(){return K9n(this.a)},I(xP,"Predicates/AndPredicate",589),D(419,2096,{419:1,3:1},JS),h.Fb=function(t){var n;return De(t,419)?(n=l(t,419),Pi(this.a,n.a)):!1},h.Hb=function(){return 1502476572+es(this.a)},h.Ib=function(){return Awt+this.a+")"},h.Jb=function(t){return new JS(_H(t.Kb(this.a),"the Function passed to Optional.transform() must not return null."))},I(xP,"Present",419),D(204,1,eT),h.Nb=function(t){Za(this,t)},h.Qb=function(){jJe()},I(dn,"UnmodifiableIterator",204),D(2076,204,tT),h.Qb=function(){jJe()},h.Rb=function(t){throw ue(new Qr)},h.Wb=function(t){throw ue(new Qr)},I(dn,"UnmodifiableListIterator",2076),D(399,2076,tT),h.Ob=function(){return this.c0},h.Pb=function(){if(this.c>=this.d)throw ue(new _c);return this.Xb(this.c++)},h.Tb=function(){return this.c},h.Ub=function(){if(this.c<=0)throw ue(new _c);return this.Xb(--this.c)},h.Vb=function(){return this.c-1},h.c=0,h.d=0,I(dn,"AbstractIndexedListIterator",399),D(713,204,eT),h.Ob=function(){return tce(this)},h.Pb=function(){return z6e(this)},h.e=1,I(dn,"AbstractIterator",713),D(2084,1,{229:1}),h.Zb=function(){var t;return t=this.f,t||(this.f=this.ac())},h.Fb=function(t){return Ece(this,t)},h.Hb=function(){return es(this.Zb())},h.dc=function(){return this.gc()==0},h.ec=function(){return W8(this)},h.Ib=function(){return xc(this.Zb())},I(dn,"AbstractMultimap",2084),D(742,2084,Jm),h.$b=function(){mV(this)},h._b=function(t){return iZe(this,t)},h.ac=function(){return new Lk(this,this.c)},h.ic=function(t){return this.hc()},h.bc=function(){return new q5(this,this.c)},h.jc=function(){return this.mc(this.hc())},h.kc=function(){return new EJe(this)},h.lc=function(){return Iue(this.c.vc().Nc(),new P,64,this.d)},h.cc=function(t){return $i(this,t)},h.fc=function(t){return DN(this,t)},h.gc=function(){return this.d},h.mc=function(t){return Cn(),new $a(t)},h.nc=function(){return new kJe(this)},h.oc=function(){return Iue(this.c.Cc().Nc(),new A,64,this.d)},h.pc=function(t,n){return new YH(this,t,n,null)},h.d=0,I(dn,"AbstractMapBasedMultimap",742),D(1696,742,Jm),h.hc=function(){return new Bu(this.a)},h.jc=function(){return Cn(),Cn(),_o},h.cc=function(t){return l($i(this,t),15)},h.fc=function(t){return l(DN(this,t),15)},h.Zb=function(){return ex(this)},h.Fb=function(t){return Ece(this,t)},h.qc=function(t){return l($i(this,t),15)},h.rc=function(t){return l(DN(this,t),15)},h.mc=function(t){return ioe(l(t,15))},h.pc=function(t,n){return _ct(this,t,l(n,15),null)},I(dn,"AbstractListMultimap",1696),D(748,1,Oa),h.Nb=function(t){Za(this,t)},h.Ob=function(){return this.c.Ob()||this.e.Ob()},h.Pb=function(){var t;return this.e.Ob()||(t=l(this.c.Pb(),44),this.b=t.ld(),this.a=l(t.md(),16),this.e=this.a.Kc()),this.sc(this.b,this.e.Pb())},h.Qb=function(){this.e.Qb(),l(Lf(this.a),16).dc()&&this.c.Qb(),--this.d.d},I(dn,"AbstractMapBasedMultimap/Itr",748),D(1129,748,Oa,kJe),h.sc=function(t,n){return n},I(dn,"AbstractMapBasedMultimap/1",1129),D(1130,1,{},A),h.Kb=function(t){return l(t,16).Nc()},I(dn,"AbstractMapBasedMultimap/1methodref$spliterator$Type",1130),D(1131,748,Oa,EJe),h.sc=function(t,n){return new iw(t,n)},I(dn,"AbstractMapBasedMultimap/2",1131);var HSe=ks(Lr,"Map");D(2065,1,Ww),h.wc=function(t){mA(this,t)},h.yc=function(t,n,r){return qce(this,t,n,r)},h.$b=function(){this.vc().$b()},h.tc=function(t){return gue(this,t)},h._b=function(t){return!!Dxe(this,t,!1)},h.uc=function(t){var n,r,a;for(r=this.vc().Kc();r.Ob();)if(n=l(r.Pb(),44),a=n.md(),qe(t)===qe(a)||t!=null&&Pi(t,a))return!0;return!1},h.Fb=function(t){var n,r,a;if(t===this)return!0;if(!De(t,85)||(a=l(t,85),this.gc()!=a.gc()))return!1;for(r=a.vc().Kc();r.Ob();)if(n=l(r.Pb(),44),!this.tc(n))return!1;return!0},h.xc=function(t){return hc(Dxe(this,t,!1))},h.Hb=function(){return I7e(this.vc())},h.dc=function(){return this.gc()==0},h.ec=function(){return new br(this)},h.zc=function(t,n){throw ue(new Hp("Put not supported on this map"))},h.Ac=function(t){bA(this,t)},h.Bc=function(t){return hc(Dxe(this,t,!0))},h.gc=function(){return this.vc().gc()},h.Ib=function(){return Igt(this)},h.Cc=function(){return new gi(this)},I(Lr,"AbstractMap",2065),D(2085,2065,Ww),h.bc=function(){return new Yz(this)},h.vc=function(){return Est(this)},h.ec=function(){var t;return t=this.g,t||(this.g=this.bc())},h.Cc=function(){var t;return t=this.i,t||(this.i=new WZe(this))},I(dn,"Maps/ViewCachingAbstractMap",2085),D(402,2085,Ww,Lk),h.xc=function(t){return fwn(this,t)},h.Bc=function(t){return Pyn(this,t)},h.$b=function(){this.d==this.e.c?this.e.$b():iH(new V4e(this))},h._b=function(t){return i1t(this.d,t)},h.Ec=function(){return new pz(this)},h.Dc=function(){return this.Ec()},h.Fb=function(t){return this===t||Pi(this.d,t)},h.Hb=function(){return es(this.d)},h.ec=function(){return this.e.ec()},h.gc=function(){return this.d.gc()},h.Ib=function(){return xc(this.d)},I(dn,"AbstractMapBasedMultimap/AsMap",402);var Fh=ks(Vc,"Iterable");D(31,1,Wy),h.Jc=function(t){to(this,t)},h.Lc=function(){return this.Oc()},h.Nc=function(){return new kn(this,0)},h.Oc=function(){return new bn(null,this.Nc())},h.Fc=function(t){throw ue(new Hp("Add not supported on this collection"))},h.Gc=function(t){return Ka(this,t)},h.$b=function(){M5e(this)},h.Hc=function(t){return Ny(this,t,!1)},h.Ic=function(t){return EN(this,t)},h.dc=function(){return this.gc()==0},h.Mc=function(t){return Ny(this,t,!0)},h.Pc=function(){return e5e(this)},h.Qc=function(t){return PA(this,t)},h.Ib=function(){return Tb(this)},I(Lr,"AbstractCollection",31);var jf=ks(Lr,"Set");D(q1,31,Tl),h.Nc=function(){return new kn(this,1)},h.Fb=function(t){return Y1t(this,t)},h.Hb=function(){return I7e(this)},I(Lr,"AbstractSet",q1),D(2068,q1,Tl),I(dn,"Sets/ImprovedAbstractSet",2068),D(2069,2068,Tl),h.$b=function(){this.Rc().$b()},h.Hc=function(t){return O1t(this,t)},h.dc=function(){return this.Rc().dc()},h.Mc=function(t){var n;return this.Hc(t)&&De(t,44)?(n=l(t,44),this.Rc().ec().Mc(n.ld())):!1},h.gc=function(){return this.Rc().gc()},I(dn,"Maps/EntrySet",2069),D(1127,2069,Tl,pz),h.Hc=function(t){return s8e(this.a.d.vc(),t)},h.Kc=function(){return new V4e(this.a)},h.Rc=function(){return this.a},h.Mc=function(t){var n;return s8e(this.a.d.vc(),t)?(n=l(Lf(l(t,44)),44),evn(this.a.e,n.ld()),!0):!1},h.Nc=function(){return NO(this.a.d.vc().Nc(),new bz(this.a))},I(dn,"AbstractMapBasedMultimap/AsMap/AsMapEntries",1127),D(1128,1,{},bz),h.Kb=function(t){return Cut(this.a,l(t,44))},I(dn,"AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type",1128),D(746,1,Oa,V4e),h.Nb=function(t){Za(this,t)},h.Pb=function(){var t;return t=l(this.b.Pb(),44),this.a=l(t.md(),16),Cut(this.c,t)},h.Ob=function(){return this.b.Ob()},h.Qb=function(){Rk(!!this.a),this.b.Qb(),this.c.e.d-=this.a.gc(),this.a.$b(),this.a=null},I(dn,"AbstractMapBasedMultimap/AsMap/AsMapIterator",746),D(542,2068,Tl,Yz),h.$b=function(){this.b.$b()},h.Hc=function(t){return this.b._b(t)},h.Jc=function(t){Xr(t),this.b.wc(new xz(t))},h.dc=function(){return this.b.dc()},h.Kc=function(){return new c_(this.b.vc().Kc())},h.Mc=function(t){return this.b._b(t)?(this.b.Bc(t),!0):!1},h.gc=function(){return this.b.gc()},I(dn,"Maps/KeySet",542),D(327,542,Tl,q5),h.$b=function(){var t;iH((t=this.b.vc().Kc(),new g3e(this,t)))},h.Ic=function(t){return this.b.ec().Ic(t)},h.Fb=function(t){return this===t||Pi(this.b.ec(),t)},h.Hb=function(){return es(this.b.ec())},h.Kc=function(){var t;return t=this.b.vc().Kc(),new g3e(this,t)},h.Mc=function(t){var n,r;return r=0,n=l(this.b.Bc(t),16),n&&(r=n.gc(),n.$b(),this.a.d-=r),r>0},h.Nc=function(){return this.b.ec().Nc()},I(dn,"AbstractMapBasedMultimap/KeySet",327),D(747,1,Oa,g3e),h.Nb=function(t){Za(this,t)},h.Ob=function(){return this.c.Ob()},h.Pb=function(){return this.a=l(this.c.Pb(),44),this.a.ld()},h.Qb=function(){var t;Rk(!!this.a),t=l(this.a.md(),16),this.c.Qb(),this.b.a.d-=t.gc(),t.$b(),this.a=null},I(dn,"AbstractMapBasedMultimap/KeySet/1",747),D(503,402,{85:1,133:1},_O),h.bc=function(){return this.Sc()},h.ec=function(){return this.Uc()},h.Sc=function(){return new tO(this.c,this.Wc())},h.Tc=function(){return this.Wc().Tc()},h.Uc=function(){var t;return t=this.b,t||(this.b=this.Sc())},h.Vc=function(){return this.Wc().Vc()},h.Wc=function(){return l(this.d,133)},I(dn,"AbstractMapBasedMultimap/SortedAsMap",503),D(446,503,Zke,q_),h.bc=function(){return new Ak(this.a,l(l(this.d,133),139))},h.Sc=function(){return new Ak(this.a,l(l(this.d,133),139))},h.ec=function(){var t;return t=this.b,l(t||(this.b=new Ak(this.a,l(l(this.d,133),139))),277)},h.Uc=function(){var t;return t=this.b,l(t||(this.b=new Ak(this.a,l(l(this.d,133),139))),277)},h.Wc=function(){return l(l(this.d,133),139)},h.Xc=function(t){return l(l(this.d,133),139).Xc(t)},h.Yc=function(t){return l(l(this.d,133),139).Yc(t)},h.Zc=function(t,n){return new q_(this.a,l(l(this.d,133),139).Zc(t,n))},h.$c=function(t){return l(l(this.d,133),139).$c(t)},h._c=function(t){return l(l(this.d,133),139)._c(t)},h.ad=function(t,n){return new q_(this.a,l(l(this.d,133),139).ad(t,n))},I(dn,"AbstractMapBasedMultimap/NavigableAsMap",446),D(502,327,Lwt,tO),h.Nc=function(){return this.b.ec().Nc()},I(dn,"AbstractMapBasedMultimap/SortedKeySet",502),D(401,502,eEe,Ak),I(dn,"AbstractMapBasedMultimap/NavigableKeySet",401),D(551,31,Wy,YH),h.Fc=function(t){var n,r;return Ql(this),r=this.d.dc(),n=this.d.Fc(t),n&&(++this.f.d,r&&DO(this)),n},h.Gc=function(t){var n,r,a;return t.dc()?!1:(a=(Ql(this),this.d.gc()),n=this.d.Gc(t),n&&(r=this.d.gc(),this.f.d+=r-a,a==0&&DO(this)),n)},h.$b=function(){var t;t=(Ql(this),this.d.gc()),t!=0&&(this.d.$b(),this.f.d-=t,lH(this))},h.Hc=function(t){return Ql(this),this.d.Hc(t)},h.Ic=function(t){return Ql(this),this.d.Ic(t)},h.Fb=function(t){return t===this?!0:(Ql(this),Pi(this.d,t))},h.Hb=function(){return Ql(this),es(this.d)},h.Kc=function(){return Ql(this),new _4e(this)},h.Mc=function(t){var n;return Ql(this),n=this.d.Mc(t),n&&(--this.f.d,lH(this)),n},h.gc=function(){return Rtt(this)},h.Nc=function(){return Ql(this),this.d.Nc()},h.Ib=function(){return Ql(this),xc(this.d)},I(dn,"AbstractMapBasedMultimap/WrappedCollection",551);var mf=ks(Lr,"List");D(744,551,{20:1,31:1,16:1,15:1},r5e),h.jd=function(t){$m(this,t)},h.Nc=function(){return Ql(this),this.d.Nc()},h.bd=function(t,n){var r;Ql(this),r=this.d.dc(),l(this.d,15).bd(t,n),++this.a.d,r&&DO(this)},h.cd=function(t,n){var r,a,o;return n.dc()?!1:(o=(Ql(this),this.d.gc()),r=l(this.d,15).cd(t,n),r&&(a=this.d.gc(),this.a.d+=a-o,o==0&&DO(this)),r)},h.Xb=function(t){return Ql(this),l(this.d,15).Xb(t)},h.dd=function(t){return Ql(this),l(this.d,15).dd(t)},h.ed=function(){return Ql(this),new gnt(this)},h.fd=function(t){return Ql(this),new Fat(this,t)},h.gd=function(t){var n;return Ql(this),n=l(this.d,15).gd(t),--this.a.d,lH(this),n},h.hd=function(t,n){return Ql(this),l(this.d,15).hd(t,n)},h.kd=function(t,n){return Ql(this),_ct(this.a,this.e,l(this.d,15).kd(t,n),this.b?this.b:this)},I(dn,"AbstractMapBasedMultimap/WrappedList",744),D(1126,744,{20:1,31:1,16:1,15:1,59:1},rrt),I(dn,"AbstractMapBasedMultimap/RandomAccessWrappedList",1126),D(628,1,Oa,_4e),h.Nb=function(t){Za(this,t)},h.Ob=function(){return Yk(this),this.b.Ob()},h.Pb=function(){return Yk(this),this.b.Pb()},h.Qb=function(){znt(this)},I(dn,"AbstractMapBasedMultimap/WrappedCollection/WrappedIterator",628),D(745,628,lg,gnt,Fat),h.Qb=function(){znt(this)},h.Rb=function(t){var n;n=Rtt(this.a)==0,(Yk(this),l(this.b,128)).Rb(t),++this.a.a.d,n&&DO(this.a)},h.Sb=function(){return(Yk(this),l(this.b,128)).Sb()},h.Tb=function(){return(Yk(this),l(this.b,128)).Tb()},h.Ub=function(){return(Yk(this),l(this.b,128)).Ub()},h.Vb=function(){return(Yk(this),l(this.b,128)).Vb()},h.Wb=function(t){(Yk(this),l(this.b,128)).Wb(t)},I(dn,"AbstractMapBasedMultimap/WrappedList/WrappedListIterator",745),D(743,551,Lwt,Gye),h.Nc=function(){return Ql(this),this.d.Nc()},I(dn,"AbstractMapBasedMultimap/WrappedSortedSet",743),D(1125,743,eEe,unt),I(dn,"AbstractMapBasedMultimap/WrappedNavigableSet",1125),D(1124,551,Tl,Trt),h.Nc=function(){return Ql(this),this.d.Nc()},I(dn,"AbstractMapBasedMultimap/WrappedSet",1124),D(1133,1,{},P),h.Kb=function(t){return lvn(l(t,44))},I(dn,"AbstractMapBasedMultimap/lambda$1$Type",1133),D(1132,1,{},bie),h.Kb=function(t){return new iw(this.a,t)},I(dn,"AbstractMapBasedMultimap/lambda$2$Type",1132);var uv=ks(Lr,"Map/Entry");D(358,1,Nle),h.Fb=function(t){var n;return De(t,44)?(n=l(t,44),yd(this.ld(),n.ld())&&yd(this.md(),n.md())):!1},h.Hb=function(){var t,n;return t=this.ld(),n=this.md(),(t==null?0:es(t))^(n==null?0:es(n))},h.nd=function(t){throw ue(new Qr)},h.Ib=function(){return this.ld()+"="+this.md()},I(dn,Mwt,358),D(2086,31,Wy),h.$b=function(){this.od().$b()},h.Hc=function(t){var n;return De(t,44)?(n=l(t,44),Dbn(this.od(),n.ld(),n.md())):!1},h.Mc=function(t){var n;return De(t,44)?(n=l(t,44),cct(this.od(),n.ld(),n.md())):!1},h.gc=function(){return this.od().d},I(dn,"Multimaps/Entries",2086),D(749,2086,Wy,vz),h.Kc=function(){return this.a.kc()},h.od=function(){return this.a},h.Nc=function(){return this.a.lc()},I(dn,"AbstractMultimap/Entries",749),D(750,749,Tl,Uwe),h.Nc=function(){return this.a.lc()},h.Fb=function(t){return Qxe(this,t)},h.Hb=function(){return wft(this)},I(dn,"AbstractMultimap/EntrySet",750),D(751,31,Wy,Q2),h.$b=function(){this.a.$b()},h.Hc=function(t){return Lyn(this.a,t)},h.Kc=function(){return this.a.nc()},h.gc=function(){return this.a.d},h.Nc=function(){return this.a.oc()},I(dn,"AbstractMultimap/Values",751),D(2087,31,{849:1,20:1,31:1,16:1}),h.Jc=function(t){Xr(t),V5(this).Jc(new kie(t))},h.Nc=function(){var t;return t=V5(this).Nc(),Iue(t,new pe,64|t.yd()&1296,this.a.d)},h.Fc=function(t){return Zwe(),!0},h.Gc=function(t){return Xr(this),Xr(t),De(t,552)?Nbn(l(t,849)):!t.dc()&&Goe(this,t.Kc())},h.Hc=function(t){var n;return n=l(Oy(ex(this.a),t),16),(n?n.gc():0)>0},h.Fb=function(t){return nTn(this,t)},h.Hb=function(){return es(V5(this))},h.dc=function(){return V5(this).dc()},h.Mc=function(t){return Upt(this,t,1)>0},h.Ib=function(){return xc(V5(this))},I(dn,"AbstractMultiset",2087),D(2089,2068,Tl),h.$b=function(){mV(this.a.a)},h.Hc=function(t){var n,r;return De(t,504)?(r=l(t,425),l(r.a.md(),16).gc()<=0?!1:(n=Pot(this.a,r.a.ld()),n==l(r.a.md(),16).gc())):!1},h.Mc=function(t){var n,r,a,o;return De(t,504)&&(r=l(t,425),n=r.a.ld(),a=l(r.a.md(),16).gc(),a!=0)?(o=this.a,Gkn(o,n,a)):!1},I(dn,"Multisets/EntrySet",2089),D(1139,2089,Tl,mie),h.Kc=function(){return new AJe(Est(ex(this.a.a)).Kc())},h.gc=function(){return ex(this.a.a).gc()},I(dn,"AbstractMultiset/EntrySet",1139),D(627,742,Jm),h.hc=function(){return this.pd()},h.jc=function(){return this.qd()},h.cc=function(t){return this.rd(t)},h.fc=function(t){return this.sd(t)},h.Zb=function(){var t;return t=this.f,t||(this.f=this.ac())},h.qd=function(){return Cn(),Cn(),hK},h.Fb=function(t){return Ece(this,t)},h.rd=function(t){return l($i(this,t),21)},h.sd=function(t){return l(DN(this,t),21)},h.mc=function(t){return Cn(),new Ek(l(t,21))},h.pc=function(t,n){return new Trt(this,t,l(n,21))},I(dn,"AbstractSetMultimap",627),D(1723,627,Jm),h.hc=function(){return new Kp(this.b)},h.pd=function(){return new Kp(this.b)},h.jc=function(){return T5e(new Kp(this.b))},h.qd=function(){return T5e(new Kp(this.b))},h.cc=function(t){return l(l($i(this,t),21),87)},h.rd=function(t){return l(l($i(this,t),21),87)},h.fc=function(t){return l(l(DN(this,t),21),87)},h.sd=function(t){return l(l(DN(this,t),21),87)},h.mc=function(t){return De(t,277)?T5e(l(t,277)):(Cn(),new Dye(l(t,87)))},h.Zb=function(){var t;return t=this.f,t||(this.f=De(this.c,139)?new q_(this,l(this.c,139)):De(this.c,133)?new _O(this,l(this.c,133)):new Lk(this,this.c))},h.pc=function(t,n){return De(n,277)?new unt(this,t,l(n,277)):new Gye(this,t,l(n,87))},I(dn,"AbstractSortedSetMultimap",1723),D(1724,1723,Jm),h.Zb=function(){var t;return t=this.f,l(l(t||(this.f=De(this.c,139)?new q_(this,l(this.c,139)):De(this.c,133)?new _O(this,l(this.c,133)):new Lk(this,this.c)),133),139)},h.ec=function(){var t;return t=this.i,l(l(t||(this.i=De(this.c,139)?new Ak(this,l(this.c,139)):De(this.c,133)?new tO(this,l(this.c,133)):new q5(this,this.c)),87),277)},h.bc=function(){return De(this.c,139)?new Ak(this,l(this.c,139)):De(this.c,133)?new tO(this,l(this.c,133)):new q5(this,this.c)},I(dn,"AbstractSortedKeySortedSetMultimap",1724),D(2109,1,{2046:1}),h.Fb=function(t){return _8n(this,t)},h.Hb=function(){var t;return I7e((t=this.g,t||(this.g=new $I(this))))},h.Ib=function(){var t;return Igt((t=this.f,t||(this.f=new _ye(this))))},I(dn,"AbstractTable",2109),D(679,q1,Tl,$I),h.$b=function(){$Je()},h.Hc=function(t){var n,r;return De(t,479)?(n=l(t,697),r=l(Oy(Kst(this.a),ab(n.c.e,n.b)),85),!!r&&s8e(r.vc(),new iw(ab(n.c.c,n.a),ox(n.c,n.b,n.a)))):!1},h.Kc=function(){return Dpn(this.a)},h.Mc=function(t){var n,r;return De(t,479)?(n=l(t,697),r=l(Oy(Kst(this.a),ab(n.c.e,n.b)),85),!!r&&c4n(r.vc(),new iw(ab(n.c.c,n.a),ox(n.c,n.b,n.a)))):!1},h.gc=function(){return Xit(this.a)},h.Nc=function(){return Fbn(this.a)},I(dn,"AbstractTable/CellSet",679),D(2025,31,Wy,wie),h.$b=function(){$Je()},h.Hc=function(t){return wxn(this.a,t)},h.Kc=function(){return Ipn(this.a)},h.gc=function(){return Xit(this.a)},h.Nc=function(){return oct(this.a)},I(dn,"AbstractTable/Values",2025),D(1697,1696,Jm),I(dn,"ArrayListMultimapGwtSerializationDependencies",1697),D(520,1697,Jm,nse,G5e),h.hc=function(){return new Bu(this.a)},h.a=0,I(dn,"ArrayListMultimap",520),D(678,2109,{678:1,2046:1,3:1},i2t),I(dn,"ArrayTable",678),D(2021,399,tT,qnt),h.Xb=function(t){return new F7e(this.a,t)},I(dn,"ArrayTable/1",2021),D(2022,1,{},gie),h.td=function(t){return new F7e(this.a,t)},I(dn,"ArrayTable/1methodref$getCell$Type",2022),D(2110,1,{697:1}),h.Fb=function(t){var n;return t===this?!0:De(t,479)?(n=l(t,697),yd(ab(this.c.e,this.b),ab(n.c.e,n.b))&&yd(ab(this.c.c,this.a),ab(n.c.c,n.a))&&yd(ox(this.c,this.b,this.a),ox(n.c,n.b,n.a))):!1},h.Hb=function(){return MN(he(le(wa,1),Rn,1,5,[ab(this.c.e,this.b),ab(this.c.c,this.a),ox(this.c,this.b,this.a)]))},h.Ib=function(){return"("+ab(this.c.e,this.b)+","+ab(this.c.c,this.a)+")="+ox(this.c,this.b,this.a)},I(dn,"Tables/AbstractCell",2110),D(479,2110,{479:1,697:1},F7e),h.a=0,h.b=0,h.d=0,I(dn,"ArrayTable/2",479),D(2024,1,{},pie),h.td=function(t){return Ilt(this.a,t)},I(dn,"ArrayTable/2methodref$getValue$Type",2024),D(2023,399,tT,Hnt),h.Xb=function(t){return Ilt(this.a,t)},I(dn,"ArrayTable/3",2023),D(2077,2065,Ww),h.$b=function(){iH(this.kc())},h.vc=function(){return new yz(this)},h.lc=function(){return new _at(this.kc(),this.gc())},I(dn,"Maps/IteratorBasedAbstractMap",2077),D(842,2077,Ww),h.$b=function(){throw ue(new Qr)},h._b=function(t){return sZe(this.c,t)},h.kc=function(){return new Vnt(this,this.c.b.c.gc())},h.lc=function(){return Cae(this.c.b.c.gc(),16,new mz(this))},h.xc=function(t){var n;return n=l(H_(this.c,t),17),n?this.vd(n.a):null},h.dc=function(){return this.c.b.c.dc()},h.ec=function(){return Oae(this.c)},h.zc=function(t,n){var r;if(r=l(H_(this.c,t),17),!r)throw ue(new Yn(this.ud()+" "+t+" not in "+Oae(this.c)));return this.wd(r.a,n)},h.Bc=function(t){throw ue(new Qr)},h.gc=function(){return this.c.b.c.gc()},I(dn,"ArrayTable/ArrayMap",842),D(2020,1,{},mz),h.td=function(t){return Yst(this.a,t)},I(dn,"ArrayTable/ArrayMap/0methodref$getEntry$Type",2020),D(2018,358,Nle,DZe),h.ld=function(){return Uhn(this.a,this.b)},h.md=function(){return this.a.vd(this.b)},h.nd=function(t){return this.a.wd(this.b,t)},h.b=0,I(dn,"ArrayTable/ArrayMap/1",2018),D(2019,399,tT,Vnt),h.Xb=function(t){return Yst(this.a,t)},I(dn,"ArrayTable/ArrayMap/2",2019),D(2017,842,Ww,Bst),h.ud=function(){return"Column"},h.vd=function(t){return ox(this.b,this.a,t)},h.wd=function(t,n){return s0t(this.b,this.a,t,n)},h.a=0,I(dn,"ArrayTable/Row",2017),D(843,842,Ww,_ye),h.vd=function(t){return new Bst(this.a,t)},h.zc=function(t,n){return l(n,85),fun()},h.wd=function(t,n){return l(n,85),dun()},h.ud=function(){return"Row"},I(dn,"ArrayTable/RowMap",843),D(1157,1,Ph,IZe),h.Ad=function(t){return(this.a.yd()&-262&t)!=0},h.yd=function(){return this.a.yd()&-262},h.zd=function(){return this.a.zd()},h.Nb=function(t){this.a.Nb(new NZe(t,this.b))},h.Bd=function(t){return this.a.Bd(new OZe(t,this.b))},I(dn,"CollectSpliterators/1",1157),D(1158,1,fr,OZe),h.Cd=function(t){this.a.Cd(this.b.Kb(t))},I(dn,"CollectSpliterators/1/lambda$0$Type",1158),D(1159,1,fr,NZe),h.Cd=function(t){this.a.Cd(this.b.Kb(t))},I(dn,"CollectSpliterators/1/lambda$1$Type",1159),D(1154,1,Ph,sit),h.Ad=function(t){return((16464|this.b)&t)!=0},h.yd=function(){return 16464|this.b},h.zd=function(){return this.a.zd()},h.Nb=function(t){this.a.Qe(new BZe(t,this.c))},h.Bd=function(t){return this.a.Re(new PZe(t,this.c))},h.b=0,I(dn,"CollectSpliterators/1WithCharacteristics",1154),D(1155,1,kP,PZe),h.Dd=function(t){this.a.Cd(this.b.td(t))},I(dn,"CollectSpliterators/1WithCharacteristics/lambda$0$Type",1155),D(1156,1,kP,BZe),h.Dd=function(t){this.a.Cd(this.b.td(t))},I(dn,"CollectSpliterators/1WithCharacteristics/lambda$1$Type",1156),D(1150,1,Ph),h.Ad=function(t){return(this.a&t)!=0},h.yd=function(){return this.a},h.zd=function(){return this.e&&(this.b=pye(this.b,this.e.zd())),pye(this.b,0)},h.Nb=function(t){this.e&&(this.e.Nb(t),this.e=null),this.c.Nb(new FZe(this,t)),this.b=0},h.Bd=function(t){for(;;){if(this.e&&this.e.Bd(t))return I_(this.b,EP)&&(this.b=Df(this.b,1)),!0;if(this.e=null,!this.c.Bd(new yie(this)))return!1}},h.a=0,h.b=0,I(dn,"CollectSpliterators/FlatMapSpliterator",1150),D(1152,1,fr,yie),h.Cd=function(t){Hfn(this.a,t)},I(dn,"CollectSpliterators/FlatMapSpliterator/lambda$0$Type",1152),D(1153,1,fr,FZe),h.Cd=function(t){gpn(this.a,this.b,t)},I(dn,"CollectSpliterators/FlatMapSpliterator/lambda$1$Type",1153),D(1151,1150,Ph,Cct),I(dn,"CollectSpliterators/FlatMapSpliteratorOfObject",1151),D(253,1,Ple),h.Fd=function(t){return this.Ed(l(t,253))},h.Ed=function(t){var n;return t==(Gie(),y0e)?1:t==(Uie(),w0e)?-1:(n=(Zq(),vN(this.a,t.a)),n!=0?n:De(this,526)==De(t,526)?0:De(this,526)?1:-1)},h.Id=function(){return this.a},h.Fb=function(t){return rxe(this,t)},I(dn,"Cut",253),D(1823,253,Ple,xJe),h.Ed=function(t){return t==this?0:1},h.Gd=function(t){throw ue(new Swe)},h.Hd=function(t){t.a+="+∞)"},h.Id=function(){throw ue(new nc(Iwt))},h.Hb=function(){return Vg(),q8e(this)},h.Jd=function(t){return!1},h.Ib=function(){return"+∞"};var w0e;I(dn,"Cut/AboveAll",1823),D(526,253,{253:1,526:1,3:1,34:1},Xnt),h.Gd=function(t){wu((t.a+="(",t),this.a)},h.Hd=function(t){hb(wu(t,this.a),93)},h.Hb=function(){return~es(this.a)},h.Jd=function(t){return Zq(),vN(this.a,t)<0},h.Ib=function(){return"/"+this.a+"\\"},I(dn,"Cut/AboveValue",526),D(1822,253,Ple,yJe),h.Ed=function(t){return t==this?0:-1},h.Gd=function(t){t.a+="(-∞"},h.Hd=function(t){throw ue(new Swe)},h.Id=function(){throw ue(new nc(Iwt))},h.Hb=function(){return Vg(),q8e(this)},h.Jd=function(t){return!0},h.Ib=function(){return"-∞"};var y0e;I(dn,"Cut/BelowAll",1822),D(1824,253,Ple,Qnt),h.Gd=function(t){wu((t.a+="[",t),this.a)},h.Hd=function(t){hb(wu(t,this.a),41)},h.Hb=function(){return es(this.a)},h.Jd=function(t){return Zq(),vN(this.a,t)<=0},h.Ib=function(){return"\\"+this.a+"/"},I(dn,"Cut/BelowValue",1824),D(547,1,hg),h.Jc=function(t){to(this,t)},h.Ib=function(){return L4n(l(_H(this,"use Optional.orNull() instead of Optional.or(null)"),20).Kc())},I(dn,"FluentIterable",547),D(442,547,hg,P_),h.Kc=function(){return new hr(dr(this.a.Kc(),new j))},I(dn,"FluentIterable/2",442),D(1059,547,hg,snt),h.Kc=function(){return rg(this)},I(dn,"FluentIterable/3",1059),D(724,399,tT,Aye),h.Xb=function(t){return this.a[t].Kc()},I(dn,"FluentIterable/3/1",724),D(2070,1,{}),h.Ib=function(){return xc(this.Kd().b)},I(dn,"ForwardingObject",2070),D(2071,2070,Owt),h.Kd=function(){return this.Ld()},h.Jc=function(t){to(this,t)},h.Lc=function(){return this.Oc()},h.Nc=function(){return new kn(this,0)},h.Oc=function(){return new bn(null,this.Nc())},h.Fc=function(t){return this.Ld(),oZe()},h.Gc=function(t){return this.Ld(),cZe()},h.$b=function(){this.Ld(),uZe()},h.Hc=function(t){return this.Ld().Hc(t)},h.Ic=function(t){return this.Ld().Ic(t)},h.dc=function(){return this.Ld().b.dc()},h.Kc=function(){return this.Ld().Kc()},h.Mc=function(t){return this.Ld(),lZe()},h.gc=function(){return this.Ld().b.gc()},h.Pc=function(){return this.Ld().Pc()},h.Qc=function(t){return this.Ld().Qc(t)},I(dn,"ForwardingCollection",2071),D(2078,31,tEe),h.Kc=function(){return this.Od()},h.Fc=function(t){throw ue(new Qr)},h.Gc=function(t){throw ue(new Qr)},h.Md=function(){var t;return t=this.c,t||(this.c=this.Nd())},h.$b=function(){throw ue(new Qr)},h.Hc=function(t){return t!=null&&Ny(this,t,!1)},h.Nd=function(){switch(this.gc()){case 0:return ww(),ww(),x0e;case 1:return ww(),new Sae(Xr(this.Od().Pb()));default:return new o5e(this,this.Pc())}},h.Mc=function(t){throw ue(new Qr)},I(dn,"ImmutableCollection",2078),D(727,2078,tEe,Twe),h.Kc=function(){return cx(this.a.Kc())},h.Hc=function(t){return t!=null&&this.a.Hc(t)},h.Ic=function(t){return this.a.Ic(t)},h.dc=function(){return this.a.dc()},h.Od=function(){return cx(this.a.Kc())},h.gc=function(){return this.a.gc()},h.Pc=function(){return this.a.Pc()},h.Qc=function(t){return this.a.Qc(t)},h.Ib=function(){return xc(this.a)},I(dn,"ForwardingImmutableCollection",727),D(307,2078,nT),h.Kc=function(){return this.Od()},h.ed=function(){return this.Pd(0)},h.fd=function(t){return this.Pd(t)},h.jd=function(t){$m(this,t)},h.Nc=function(){return new kn(this,16)},h.kd=function(t,n){return this.Qd(t,n)},h.bd=function(t,n){throw ue(new Qr)},h.cd=function(t,n){throw ue(new Qr)},h.Md=function(){return this},h.Fb=function(t){return VEn(this,t)},h.Hb=function(){return R3n(this)},h.dd=function(t){return t==null?-1:o7n(this,t)},h.Od=function(){return this.Pd(0)},h.Pd=function(t){return iae(this,t)},h.gd=function(t){throw ue(new Qr)},h.hd=function(t,n){throw ue(new Qr)},h.Qd=function(t,n){var r;return RV((r=new KZe(this),new Zp(r,t,n)))};var x0e;I(dn,"ImmutableList",307),D(2105,307,nT),h.Kc=function(){return cx(this.Rd().Kc())},h.kd=function(t,n){return RV(this.Rd().kd(t,n))},h.Hc=function(t){return t!=null&&this.Rd().Hc(t)},h.Ic=function(t){return this.Rd().Ic(t)},h.Fb=function(t){return Pi(this.Rd(),t)},h.Xb=function(t){return ab(this,t)},h.Hb=function(){return es(this.Rd())},h.dd=function(t){return this.Rd().dd(t)},h.dc=function(){return this.Rd().dc()},h.Od=function(){return cx(this.Rd().Kc())},h.gc=function(){return this.Rd().gc()},h.Qd=function(t,n){return RV(this.Rd().kd(t,n))},h.Pc=function(){return this.Rd().Qc(We(wa,Rn,1,this.Rd().gc(),5,1))},h.Qc=function(t){return this.Rd().Qc(t)},h.Ib=function(){return xc(this.Rd())},I(dn,"ForwardingImmutableList",2105),D(729,1,rT),h.vc=function(){return Mm(this)},h.wc=function(t){mA(this,t)},h.ec=function(){return Oae(this)},h.yc=function(t,n,r){return qce(this,t,n,r)},h.Cc=function(){return this.Vd()},h.$b=function(){throw ue(new Qr)},h._b=function(t){return this.xc(t)!=null},h.uc=function(t){return this.Vd().Hc(t)},h.Td=function(){return new LQe(this)},h.Ud=function(){return new MQe(this)},h.Fb=function(t){return Myn(this,t)},h.Hb=function(){return Mm(this).Hb()},h.dc=function(){return this.gc()==0},h.zc=function(t,n){return hun()},h.Bc=function(t){throw ue(new Qr)},h.Ib=function(){return m9n(this)},h.Vd=function(){return this.e?this.e:this.e=this.Ud()},h.c=null,h.d=null,h.e=null;var i6t;I(dn,"ImmutableMap",729),D(730,729,rT),h._b=function(t){return sZe(this,t)},h.uc=function(t){return ZZe(this.b,t)},h.Sd=function(){return t1t(new vie(this))},h.Td=function(){return t1t(mat(this.b))},h.Ud=function(){return wd(),new Twe(bat(this.b))},h.Fb=function(t){return eet(this.b,t)},h.xc=function(t){return H_(this,t)},h.Hb=function(){return es(this.b.c)},h.dc=function(){return this.b.c.dc()},h.gc=function(){return this.b.c.gc()},h.Ib=function(){return xc(this.b.c)},I(dn,"ForwardingImmutableMap",730),D(2072,2071,Ble),h.Kd=function(){return this.Wd()},h.Ld=function(){return this.Wd()},h.Nc=function(){return new kn(this,1)},h.Fb=function(t){return t===this||this.Wd().Fb(t)},h.Hb=function(){return this.Wd().Hb()},I(dn,"ForwardingSet",2072),D(1085,2072,Ble,vie),h.Kd=function(){return Kk(this.a.b)},h.Ld=function(){return Kk(this.a.b)},h.Hc=function(t){if(De(t,44)&&l(t,44).ld()==null)return!1;try{return JZe(Kk(this.a.b),t)}catch(n){if(n=bs(n),De(n,212))return!1;throw ue(n)}},h.Wd=function(){return Kk(this.a.b)},h.Qc=function(t){var n;return n=tot(Kk(this.a.b),t),Kk(this.a.b).b.gc()=0?"+":"")+(r/60|0),n=Iq(b.Math.abs(r)%60),(Vgt(),E6t)[this.q.getDay()]+" "+T6t[this.q.getMonth()]+" "+Iq(this.q.getDate())+" "+Iq(this.q.getHours())+":"+Iq(this.q.getMinutes())+":"+Iq(this.q.getSeconds())+" GMT"+t+n+" "+this.q.getFullYear()};var cK=I(Lr,"Date",206);D(2015,206,qwt,dgt),h.a=!1,h.b=0,h.c=0,h.d=0,h.e=0,h.f=0,h.g=!1,h.i=0,h.j=0,h.k=0,h.n=0,h.o=0,h.p=0,I("com.google.gwt.i18n.shared.impl","DateRecord",2015),D(2064,1,{}),h.pe=function(){return null},h.qe=function(){return null},h.re=function(){return null},h.se=function(){return null},h.te=function(){return null},I(Ax,"JSONValue",2064),D(221,2064,{221:1},$p,Sz),h.Fb=function(t){return De(t,221)?W5e(this.a,l(t,221).a):!1},h.oe=function(){return Bcn},h.Hb=function(){return F5e(this.a)},h.pe=function(){return this},h.Ib=function(){var t,n,r;for(r=new Th("["),n=0,t=this.a.length;n0&&(r.a+=","),wu(r,_y(this,n));return r.a+="]",r.a},I(Ax,"JSONArray",221),D(493,2064,{493:1},jc),h.oe=function(){return Fcn},h.qe=function(){return this},h.Ib=function(){return Hn(),""+this.a},h.a=!1;var h6t,f6t;I(Ax,"JSONBoolean",493),D(997,63,lp,LJe),I(Ax,"JSONException",997),D(1036,2064,{},W),h.oe=function(){return Rcn},h.Ib=function(){return ul};var d6t;I(Ax,"JSONNull",1036),D(263,2064,{263:1},vk),h.Fb=function(t){return De(t,263)?this.a==l(t,263).a:!1},h.oe=function(){return Ncn},h.Hb=function(){return j8(this.a)},h.re=function(){return this},h.Ib=function(){return this.a+""},h.a=0,I(Ax,"JSONNumber",263),D(190,2064,{190:1},M8,wk),h.Fb=function(t){return De(t,190)?W5e(this.a,l(t,190).a):!1},h.oe=function(){return Pcn},h.Hb=function(){return F5e(this.a)},h.se=function(){return this},h.Ib=function(){var t,n,r,a,o,f,g;for(g=new Th("{"),t=!0,f=ace(this,We(zt,dt,2,0,6,1)),r=f,a=0,o=r.length;a=0?":"+this.c:"")+")"},h.c=0;var a_e=I(Vc,"StackTraceElement",319);r6t={3:1,484:1,34:1,2:1};var zt=I(Vc,nEe,2);D(111,427,{484:1},Up,h_,Af),I(Vc,"StringBuffer",111),D(104,427,{484:1},tb,S5,Th),I(Vc,"StringBuilder",104),D(702,77,she,e3e),I(Vc,"StringIndexOutOfBoundsException",702),D(2145,1,{});var m6t;D(48,63,{3:1,103:1,63:1,82:1,48:1},Qr,Hp),I(Vc,"UnsupportedOperationException",48),D(247,242,{3:1,34:1,242:1,247:1},NN,h3e),h.Fd=function(t){return Fmt(this,l(t,247))},h.ue=function(){return jy(hvt(this))},h.Fb=function(t){var n;return this===t?!0:De(t,247)?(n=l(t,247),this.e==n.e&&Fmt(this,n)==0):!1},h.Hb=function(){var t;return this.b!=0?this.b:this.a<54?(t=Zc(this.f),this.b=Yr(va(t,-1)),this.b=33*this.b+Yr(va(bw(t,32),-1)),this.b=17*this.b+ua(this.e),this.b):(this.b=17*X0t(this.c)+ua(this.e),this.b)},h.Ib=function(){return hvt(this)},h.a=0,h.b=0,h.d=0,h.e=0,h.f=0;var v6t,lv,o_e,c_e,u_e,l_e,h_e,f_e,L0e=I("java.math","BigDecimal",247);D(92,242,{3:1,34:1,242:1,92:1},Qg,qot,Im,Q1t,ob),h.Fd=function(t){return K1t(this,l(t,92))},h.ue=function(){return jy(Dle(this,0))},h.Fb=function(t){return C8e(this,t)},h.Hb=function(){return X0t(this)},h.Ib=function(){return Dle(this,0)},h.b=-2,h.c=0,h.d=0,h.e=0;var w6t,uK,y6t,M0e,lK,BL,A6=I("java.math","BigInteger",92),x6t,k6t,$x,FL;D(498,2065,Ww),h.$b=function(){Nl(this)},h._b=function(t){return Hu(this,t)},h.uc=function(t){return D0t(this,t,this.i)||D0t(this,t,this.f)},h.vc=function(){return new Sr(this)},h.xc=function(t){return cr(this,t)},h.zc=function(t,n){return ki(this,t,n)},h.Bc=function(t){return ax(this,t)},h.gc=function(){return d_(this)},h.g=0,I(Lr,"AbstractHashMap",498),D(267,q1,Tl,Sr),h.$b=function(){this.a.$b()},h.Hc=function(t){return vct(this,t)},h.Kc=function(){return new qm(this.a)},h.Mc=function(t){var n;return vct(this,t)?(n=l(t,44).ld(),this.a.Bc(n),!0):!1},h.gc=function(){return this.a.gc()},I(Lr,"AbstractHashMap/EntrySet",267),D(268,1,Oa,qm),h.Nb=function(t){Za(this,t)},h.Pb=function(){return Nw(this)},h.Ob=function(){return this.b},h.Qb=function(){Klt(this)},h.b=!1,h.d=0,I(Lr,"AbstractHashMap/EntrySetIterator",268),D(426,1,Oa,kr),h.Nb=function(t){Za(this,t)},h.Ob=function(){return lse(this)},h.Pb=function(){return I5e(this)},h.Qb=function(){ph(this)},h.b=0,h.c=-1,I(Lr,"AbstractList/IteratorImpl",426),D(98,426,lg,Ua),h.Qb=function(){ph(this)},h.Rb=function(t){by(this,t)},h.Sb=function(){return this.b>0},h.Tb=function(){return this.b},h.Ub=function(){return mr(this.b>0),this.a.Xb(this.c=--this.b)},h.Vb=function(){return this.b-1},h.Wb=function(t){gy(this.c!=-1),this.a.hd(this.c,t)},I(Lr,"AbstractList/ListIteratorImpl",98),D(244,56,iT,Zp),h.bd=function(t,n){Ey(t,this.b),this.c.bd(this.a+t,n),++this.b},h.Xb=function(t){return Sn(t,this.b),this.c.Xb(this.a+t)},h.gd=function(t){var n;return Sn(t,this.b),n=this.c.gd(this.a+t),--this.b,n},h.hd=function(t,n){return Sn(t,this.b),this.c.hd(this.a+t,n)},h.gc=function(){return this.b},h.a=0,h.b=0,I(Lr,"AbstractList/SubList",244),D(266,q1,Tl,br),h.$b=function(){this.a.$b()},h.Hc=function(t){return this.a._b(t)},h.Kc=function(){var t;return t=this.a.vc().Kc(),new Mi(t)},h.Mc=function(t){return this.a._b(t)?(this.a.Bc(t),!0):!1},h.gc=function(){return this.a.gc()},I(Lr,"AbstractMap/1",266),D(541,1,Oa,Mi),h.Nb=function(t){Za(this,t)},h.Ob=function(){return this.a.Ob()},h.Pb=function(){var t;return t=l(this.a.Pb(),44),t.ld()},h.Qb=function(){this.a.Qb()},I(Lr,"AbstractMap/1/1",541),D(231,31,Wy,gi),h.$b=function(){this.a.$b()},h.Hc=function(t){return this.a.uc(t)},h.Kc=function(){var t;return t=this.a.vc().Kc(),new fs(t)},h.gc=function(){return this.a.gc()},I(Lr,"AbstractMap/2",231),D(301,1,Oa,fs),h.Nb=function(t){Za(this,t)},h.Ob=function(){return this.a.Ob()},h.Pb=function(){var t;return t=l(this.a.Pb(),44),t.md()},h.Qb=function(){this.a.Qb()},I(Lr,"AbstractMap/2/1",301),D(494,1,{494:1,44:1}),h.Fb=function(t){var n;return De(t,44)?(n=l(t,44),Jc(this.d,n.ld())&&Jc(this.e,n.md())):!1},h.ld=function(){return this.d},h.md=function(){return this.e},h.Hb=function(){return R5(this.d)^R5(this.e)},h.nd=function(t){return Zye(this,t)},h.Ib=function(){return this.d+"="+this.e},I(Lr,"AbstractMap/AbstractEntry",494),D(397,494,{494:1,397:1,44:1},cq),I(Lr,"AbstractMap/SimpleEntry",397),D(2082,1,che),h.Fb=function(t){var n;return De(t,44)?(n=l(t,44),Jc(this.ld(),n.ld())&&Jc(this.md(),n.md())):!1},h.Hb=function(){return R5(this.ld())^R5(this.md())},h.Ib=function(){return this.ld()+"="+this.md()},I(Lr,Mwt,2082),D(2090,2065,Zke),h.Xc=function(t){return rse(this.Ee(t))},h.tc=function(t){return Tut(this,t)},h._b=function(t){return e4e(this,t)},h.vc=function(){return new Rs(this)},h.Tc=function(){return Rst(this.Ge())},h.Yc=function(t){return rse(this.He(t))},h.xc=function(t){var n;return n=t,hc(this.Fe(n))},h.$c=function(t){return rse(this.Ie(t))},h.ec=function(){return new Fs(this)},h.Vc=function(){return Rst(this.Je())},h._c=function(t){return rse(this.Ke(t))},I(Lr,"AbstractNavigableMap",2090),D(629,q1,Tl,Rs),h.Hc=function(t){return De(t,44)&&Tut(this.b,l(t,44))},h.Kc=function(){return this.b.De()},h.Mc=function(t){var n;return De(t,44)?(n=l(t,44),this.b.Le(n)):!1},h.gc=function(){return this.b.gc()},I(Lr,"AbstractNavigableMap/EntrySet",629),D(1146,q1,eEe,Fs),h.Nc=function(){return new aq(this)},h.$b=function(){this.a.$b()},h.Hc=function(t){return e4e(this.a,t)},h.Kc=function(){var t;return t=this.a.vc().b.De(),new xs(t)},h.Mc=function(t){return e4e(this.a,t)?(this.a.Bc(t),!0):!1},h.gc=function(){return this.a.gc()},I(Lr,"AbstractNavigableMap/NavigableKeySet",1146),D(1147,1,Oa,xs),h.Nb=function(t){Za(this,t)},h.Ob=function(){return lse(this.a.a)},h.Pb=function(){var t;return t=ort(this.a),t.ld()},h.Qb=function(){dit(this.a)},I(Lr,"AbstractNavigableMap/NavigableKeySet/1",1147),D(2103,31,Wy),h.Fc=function(t){return K8($E(this,t),aT),!0},h.Gc=function(t){return nr(t),BO(t!=this,"Can't add a queue to itself"),Ka(this,t)},h.$b=function(){for(;Koe(this)!=null;);},I(Lr,"AbstractQueue",2103),D(310,31,{4:1,20:1,31:1,16:1},z5,dct),h.Fc=function(t){return i6e(this,t),!0},h.$b=function(){l6e(this)},h.Hc=function(t){return Zft(new nA(this),t)},h.dc=function(){return l_(this)},h.Kc=function(){return new nA(this)},h.Mc=function(t){return w2n(new nA(this),t)},h.gc=function(){return this.c-this.b&this.a.length-1},h.Nc=function(){return new kn(this,272)},h.Qc=function(t){var n;return n=this.c-this.b&this.a.length-1,t.lengthn&&Ts(t,n,null),t},h.b=0,h.c=0,I(Lr,"ArrayDeque",310),D(459,1,Oa,nA),h.Nb=function(t){Za(this,t)},h.Ob=function(){return this.a!=this.b},h.Pb=function(){return FV(this)},h.Qb=function(){Yht(this)},h.a=0,h.b=0,h.c=-1,I(Lr,"ArrayDeque/IteratorImpl",459),D(13,56,Uwt,bt,Bu,Ol),h.bd=function(t,n){pw(this,t,n)},h.Fc=function(t){return vt(this,t)},h.cd=function(t,n){return Q7e(this,t,n)},h.Gc=function(t){return ra(this,t)},h.$b=function(){ay(this.c,0)},h.Hc=function(t){return gc(this,t,0)!=-1},h.Jc=function(t){Vu(this,t)},h.Xb=function(t){return jt(this,t)},h.dd=function(t){return gc(this,t,0)},h.dc=function(){return this.c.length==0},h.Kc=function(){return new G(this)},h.gd=function(t){return t2(this,t)},h.Mc=function(t){return al(this,t)},h.ce=function(t,n){Bot(this,t,n)},h.hd=function(t,n){return rf(this,t,n)},h.gc=function(){return this.c.length},h.jd=function(t){Vs(this,t)},h.Pc=function(){return eH(this.c)},h.Qc=function(t){return j1(this,t)};var cOn=I(Lr,"ArrayList",13);D(7,1,Oa,G),h.Nb=function(t){Za(this,t)},h.Ob=function(){return Lc(this)},h.Pb=function(){return re(this)},h.Qb=function(){Q_(this)},h.a=0,h.b=-1,I(Lr,"ArrayList/1",7),D(2112,b.Function,{},Pe),h.Me=function(t,n){return Yi(t,n)},D(151,56,Gwt,Il),h.Hc=function(t){return Xht(this,t)!=-1},h.Jc=function(t){var n,r,a,o;for(nr(t),r=this.a,a=0,o=r.length;a0)throw ue(new Yn(lEe+t+" greater than "+this.e));return this.f.Te()?sot(this.c,this.b,this.a,t,n):Fot(this.c,t,n)},h.zc=function(t,n){if(!xue(this.c,this.f,t,this.b,this.a,this.e,this.d))throw ue(new Yn(t+" outside the range "+this.b+" to "+this.e));return b0t(this.c,t,n)},h.Bc=function(t){var n;return n=t,xue(this.c,this.f,n,this.b,this.a,this.e,this.d)?aot(this.c,n):null},h.Le=function(t){return yH(this,t.ld())&&L6e(this.c,t)},h.gc=function(){var t,n,r;if(this.f.Te()?this.a?n=OE(this.c,this.b,!0):n=OE(this.c,this.b,!1):n=j6e(this.c),!(n&&yH(this,n.d)&&n))return 0;for(t=0,r=new oce(this.c,this.f,this.b,this.a,this.e,this.d);lse(r.a);r.b=l(I5e(r.a),44))++t;return t},h.ad=function(t,n){if(this.f.Te()&&this.c.a.Ne(t,this.b)<0)throw ue(new Yn(lEe+t+Ywt+this.b));return this.f.Ue()?sot(this.c,t,n,this.e,this.d):Rot(this.c,t,n)},h.a=!1,h.d=!1,I(Lr,"TreeMap/SubMap",631),D(304,22,fhe,oq),h.Te=function(){return!1},h.Ue=function(){return!1};var O0e,N0e,P0e,B0e,fK=Fr(Lr,"TreeMap/SubMapType",304,Hr,Gbn,n0n);D(1143,304,fhe,hnt),h.Ue=function(){return!0},Fr(Lr,"TreeMap/SubMapType/1",1143,fK,null,null),D(1144,304,fhe,ynt),h.Te=function(){return!0},h.Ue=function(){return!0},Fr(Lr,"TreeMap/SubMapType/2",1144,fK,null,null),D(1145,304,fhe,lnt),h.Te=function(){return!0},Fr(Lr,"TreeMap/SubMapType/3",1145,fK,null,null);var M6t;D(157,q1,{3:1,20:1,31:1,16:1,277:1,21:1,87:1,157:1},Lwe,Kp,ba),h.Nc=function(){return new aq(this)},h.Fc=function(t){return jO(this,t)},h.$b=function(){this.a.$b()},h.Hc=function(t){return this.a._b(t)},h.Kc=function(){return this.a.ec().Kc()},h.Mc=function(t){return tae(this,t)},h.gc=function(){return this.a.gc()};var gOn=I(Lr,"TreeSet",157);D(1082,1,{},xo),h.Ve=function(t,n){return wfn(this.a,t,n)},I(dhe,"BinaryOperator/lambda$0$Type",1082),D(1083,1,{},lh),h.Ve=function(t,n){return yfn(this.a,t,n)},I(dhe,"BinaryOperator/lambda$1$Type",1083),D(952,1,{},Pt),h.Kb=function(t){return t},I(dhe,"Function/lambda$0$Type",952),D(395,1,ti,Wl),h.Mb=function(t){return!this.a.Mb(t)},I(dhe,"Predicate/lambda$2$Type",395),D(581,1,{581:1});var D6t=I(aL,"Handler",581);D(2107,1,yP),h.xe=function(){return"DUMMY"},h.Ib=function(){return this.xe()};var w_e;I(aL,"Level",2107),D(1706,2107,yP,Qe),h.xe=function(){return"INFO"},I(aL,"Level/LevelInfo",1706),D(1843,1,{},FQe);var F0e;I(aL,"LogManager",1843),D(1896,1,yP,fit),h.b=null,I(aL,"LogRecord",1896),D(525,1,{525:1},Soe),h.e=!1;var I6t=!1,O6t=!1,G1=!1,N6t=!1,P6t=!1;I(aL,"Logger",525),D(835,581,{581:1},Dt),I(aL,"SimpleConsoleLogHandler",835),D(108,22,{3:1,34:1,22:1,108:1},dse);var y_e,Ec,i4,oc=Fr(sa,"Collector/Characteristics",108,Hr,O2n,r0n),B6t;D(758,1,{},h5e),I(sa,"CollectorImpl",758),D(1074,1,{},kt),h.Ve=function(t,n){return d4n(l(t,213),l(n,213))},I(sa,"Collectors/10methodref$merge$Type",1074),D(1075,1,{},On),h.Kb=function(t){return gct(l(t,213))},I(sa,"Collectors/11methodref$toString$Type",1075),D(1076,1,{},Z2),h.Kb=function(t){return Hn(),!!sye(t)},I(sa,"Collectors/12methodref$test$Type",1076),D(144,1,{},ht),h.Yd=function(t,n){l(t,16).Fc(n)},I(sa,"Collectors/20methodref$add$Type",144),D(146,1,{},zr),h.Xe=function(){return new bt},I(sa,"Collectors/21methodref$ctor$Type",146),D(359,1,{},yt),h.Xe=function(){return new Ks},I(sa,"Collectors/23methodref$ctor$Type",359),D(360,1,{},ji),h.Yd=function(t,n){na(l(t,49),n)},I(sa,"Collectors/24methodref$add$Type",360),D(1069,1,{},xi),h.Ve=function(t,n){return ret(l(t,15),l(n,16))},I(sa,"Collectors/4methodref$addAll$Type",1069),D(1073,1,{},Ma),h.Yd=function(t,n){Jg(l(t,213),l(n,484))},I(sa,"Collectors/9methodref$add$Type",1073),D(1072,1,{},Lit),h.Xe=function(){return new Hm(this.a,this.b,this.c)},I(sa,"Collectors/lambda$15$Type",1072),D(1077,1,{},zs),h.Xe=function(){var t;return t=new e2,h2(t,(Hn(),!1),new bt),h2(t,!0,new bt),t},I(sa,"Collectors/lambda$22$Type",1077),D(1078,1,{},eb),h.Xe=function(){return he(le(wa,1),Rn,1,5,[this.a])},I(sa,"Collectors/lambda$25$Type",1078),D(1079,1,{},G0),h.Yd=function(t,n){jdn(this.a,jm(t))},I(sa,"Collectors/lambda$26$Type",1079),D(1080,1,{},zp),h.Ve=function(t,n){return dgn(this.a,jm(t),jm(n))},I(sa,"Collectors/lambda$27$Type",1080),D(1081,1,{},ao),h.Kb=function(t){return jm(t)[0]},I(sa,"Collectors/lambda$28$Type",1081),D(728,1,{},Tr),h.Ve=function(t,n){return U4e(t,n)},I(sa,"Collectors/lambda$4$Type",728),D(145,1,{},Fn),h.Ve=function(t,n){return Wun(l(t,16),l(n,16))},I(sa,"Collectors/lambda$42$Type",145),D(361,1,{},qn),h.Ve=function(t,n){return Yun(l(t,49),l(n,49))},I(sa,"Collectors/lambda$50$Type",361),D(362,1,{},Un),h.Kb=function(t){return l(t,49)},I(sa,"Collectors/lambda$51$Type",362),D(1068,1,{},fd),h.Yd=function(t,n){wyn(this.a,l(t,85),n)},I(sa,"Collectors/lambda$7$Type",1068),D(1070,1,{},At),h.Ve=function(t,n){return Y3n(l(t,85),l(n,85),new xi)},I(sa,"Collectors/lambda$8$Type",1070),D(1071,1,{},Wv),h.Kb=function(t){return G4n(this.a,l(t,85))},I(sa,"Collectors/lambda$9$Type",1071),D(550,1,{}),h.$e=function(){tA(this)},h.d=!1,I(sa,"TerminatableStream",550),D(827,550,hEe,Vye),h.$e=function(){tA(this)},I(sa,"DoubleStreamImpl",827),D(1847,736,Ph,Mit),h.Re=function(t){return Y6n(this,l(t,189))},h.a=null,I(sa,"DoubleStreamImpl/2",1847),D(1848,1,LP,sy),h.Pe=function(t){qln(this.a,t)},I(sa,"DoubleStreamImpl/2/lambda$0$Type",1848),D(1845,1,LP,E8),h.Pe=function(t){zln(this.a,t)},I(sa,"DoubleStreamImpl/lambda$0$Type",1845),D(1846,1,LP,x5),h.Pe=function(t){M1t(this.a,t)},I(sa,"DoubleStreamImpl/lambda$2$Type",1846),D(1397,735,Ph,wut),h.Re=function(t){return Pbn(this,l(t,202))},h.a=0,h.b=0,h.c=0,I(sa,"IntStream/5",1397),D(806,550,hEe,Uye),h.$e=function(){tA(this)},h._e=function(){return fb(this),this.a},I(sa,"IntStreamImpl",806),D(807,550,hEe,b3e),h.$e=function(){tA(this)},h._e=function(){return fb(this),Sye(),L6t},I(sa,"IntStreamImpl/Empty",807),D(1687,1,kP,T8),h.Dd=function(t){$ft(this.a,t)},I(sa,"IntStreamImpl/lambda$4$Type",1687);var pOn=ks(sa,"Stream");D(26,550,{533:1,687:1,848:1},bn),h.$e=function(){tA(this)};var zx;I(sa,"StreamImpl",26),D(1102,500,Ph,iit),h.Bd=function(t){for(;Rvn(this);){if(this.a.Bd(t))return!0;tA(this.b),this.b=null,this.a=null}return!1},I(sa,"StreamImpl/1",1102),D(1103,1,fr,ZS),h.Cd=function(t){hdn(this.a,l(t,848))},I(sa,"StreamImpl/1/lambda$0$Type",1103),D(1104,1,ti,k5),h.Mb=function(t){return na(this.a,t)},I(sa,"StreamImpl/1methodref$add$Type",1104),D(1105,500,Ph,Rat),h.Bd=function(t){var n;return this.a||(n=new bt,this.b.a.Nb(new Qd(n)),Cn(),Vs(n,this.c),this.a=new kn(n,16)),xht(this.a,t)},h.a=null,I(sa,"StreamImpl/5",1105),D(1106,1,fr,Qd),h.Cd=function(t){vt(this.a,t)},I(sa,"StreamImpl/5/2methodref$add$Type",1106),D(737,500,Ph,$6e),h.Bd=function(t){for(this.b=!1;!this.b&&this.c.Bd(new xet(this,t)););return this.b},h.b=!1,I(sa,"StreamImpl/FilterSpliterator",737),D(1096,1,fr,xet),h.Cd=function(t){ogn(this.a,this.b,t)},I(sa,"StreamImpl/FilterSpliterator/lambda$0$Type",1096),D(1091,736,Ph,Mut),h.Re=function(t){return zfn(this,l(t,189))},I(sa,"StreamImpl/MapToDoubleSpliterator",1091),D(1095,1,fr,ket),h.Cd=function(t){hln(this.a,this.b,t)},I(sa,"StreamImpl/MapToDoubleSpliterator/lambda$0$Type",1095),D(1090,735,Ph,Dut),h.Re=function(t){return qfn(this,l(t,202))},I(sa,"StreamImpl/MapToIntSpliterator",1090),D(1094,1,fr,Eet),h.Cd=function(t){fln(this.a,this.b,t)},I(sa,"StreamImpl/MapToIntSpliterator/lambda$0$Type",1094),D(734,500,Ph,C6e),h.Bd=function(t){return tit(this,t)},I(sa,"StreamImpl/MapToObjSpliterator",734),D(1093,1,fr,Tet),h.Cd=function(t){dln(this.a,this.b,t)},I(sa,"StreamImpl/MapToObjSpliterator/lambda$0$Type",1093),D(1092,500,Ph,aft),h.Bd=function(t){for(;hse(this.b,0);){if(!this.a.Bd(new wt))return!1;this.b=Df(this.b,1)}return this.a.Bd(t)},h.b=0,I(sa,"StreamImpl/SkipSpliterator",1092),D(1097,1,fr,wt),h.Cd=function(t){},I(sa,"StreamImpl/SkipSpliterator/lambda$0$Type",1097),D(626,1,fr,on),h.Cd=function(t){Eie(this,t)},I(sa,"StreamImpl/ValueConsumer",626),D(1098,1,fr,fn),h.Cd=function(t){Am()},I(sa,"StreamImpl/lambda$0$Type",1098),D(1099,1,fr,An),h.Cd=function(t){Am()},I(sa,"StreamImpl/lambda$1$Type",1099),D(1100,1,{},_1),h.Ve=function(t,n){return y0n(this.a,t,n)},I(sa,"StreamImpl/lambda$4$Type",1100),D(1101,1,fr,Cet),h.Cd=function(t){Sfn(this.b,this.a,t)},I(sa,"StreamImpl/lambda$5$Type",1101),D(1107,1,fr,Jd),h.Cd=function(t){F3n(this.a,l(t,380))},I(sa,"TerminatableStream/lambda$0$Type",1107),D(2142,1,{}),D(2014,1,{},oo),I("javaemul.internal","ConsoleLogger",2014);var bOn=0;D(2134,1,{}),D(1830,1,fr,jo),h.Cd=function(t){l(t,317)},I(oT,"BowyerWatsonTriangulation/lambda$0$Type",1830),D(1831,1,fr,Em),h.Cd=function(t){Ka(this.a,l(t,317).e)},I(oT,"BowyerWatsonTriangulation/lambda$1$Type",1831),D(1832,1,fr,$o),h.Cd=function(t){l(t,177)},I(oT,"BowyerWatsonTriangulation/lambda$2$Type",1832),D(1827,1,ii,Lz),h.Ne=function(t,n){return ymn(this.a,l(t,177),l(n,177))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(oT,"NaiveMinST/lambda$0$Type",1827),D(449,1,{},Yv),I(oT,"NodeMicroLayout",449),D(177,1,{177:1},B8),h.Fb=function(t){var n;return De(t,177)?(n=l(t,177),Jc(this.a,n.a)&&Jc(this.b,n.b)||Jc(this.a,n.b)&&Jc(this.b,n.a)):!1},h.Hb=function(){return R5(this.a)+R5(this.b)};var mOn=I(oT,"TEdge",177);D(317,1,{317:1},Cke),h.Fb=function(t){var n;return De(t,317)?(n=l(t,317),rV(this,n.a)&&rV(this,n.b)&&rV(this,n.c)):!1},h.Hb=function(){return R5(this.a)+R5(this.b)+R5(this.c)},I(oT,"TTriangle",317),D(225,1,{225:1},Nq),I(oT,"Tree",225),D(1218,1,{},Eot),I(Jwt,"Scanline",1218);var F6t=ks(Jwt,Zwt);D(1758,1,{},vht),I(gg,"CGraph",1758),D(316,1,{316:1},Sot),h.b=0,h.c=0,h.d=0,h.g=0,h.i=0,h.k=ia,I(gg,"CGroup",316),D(830,1,{},Iwe),I(gg,"CGroup/CGroupBuilder",830),D(60,1,{60:1},Rrt),h.Ib=function(){var t;return this.j?ei(this.j.Kb(this)):(Gg(dK),dK.o+"@"+(t=fw(this)>>>0,t.toString(16)))},h.f=0,h.i=ia;var dK=I(gg,"CNode",60);D(829,1,{},Owe),I(gg,"CNode/CNodeBuilder",829);var R6t;D(1590,1,{},Pa),h.ff=function(t,n){return 0},h.gf=function(t,n){return 0},I(gg,t3t,1590),D(1853,1,{},wo),h.cf=function(t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te;for(C=gs,a=new G(t.a.b);a.aa.d.c||a.d.c==f.d.c&&a.d.b0?t+this.n.d+this.n.a:0},h.kf=function(){var t,n,r,a,o;if(o=0,this.e)this.b?o=this.b.a:this.a[1][1]&&(o=this.a[1][1].kf());else if(this.g)o=E8e(this,Eue(this,null,!0));else for(n=(t1(),he(le(s4,1),it,237,0,[Gc,$u,Kc])),r=0,a=n.length;r0?o+this.n.b+this.n.c:0},h.lf=function(){var t,n,r,a,o;if(this.g)for(t=Eue(this,null,!1),r=(t1(),he(le(s4,1),it,237,0,[Gc,$u,Kc])),a=0,o=r.length;a0&&(a[0]+=this.d,r-=a[0]),a[2]>0&&(a[2]+=this.d,r-=a[2]),this.c.a=b.Math.max(0,r),this.c.d=n.d+t.d+(this.c.a-r)/2,a[1]=b.Math.max(a[1],r),x6e(this,$u,n.d+t.d+a[0]-(a[1]-r)/2,a)},h.b=null,h.d=0,h.e=!1,h.f=!1,h.g=!1;var q0e=0,gK=0;I(ev,"GridContainerCell",1538),D(471,22,{3:1,34:1,22:1,471:1},pse);var Bb,Fd,v0,W6t=Fr(ev,"HorizontalLabelAlignment",471,Hr,P2n,c0n),Y6t;D(314,217,{217:1,314:1},uot,yht,not),h.jf=function(){return Hit(this)},h.kf=function(){return j4e(this)},h.a=0,h.c=!1;var vOn=I(ev,"LabelCell",314);D(252,336,{217:1,336:1,252:1},DA),h.jf=function(){return tP(this)},h.kf=function(){return nP(this)},h.lf=function(){hle(this)},h.mf=function(){fle(this)},h.b=0,h.c=0,h.d=!1,I(ev,"StripContainerCell",252),D(1691,1,ti,Xc),h.Mb=function(t){return cun(l(t,217))},I(ev,"StripContainerCell/lambda$0$Type",1691),D(1692,1,{},Bc),h.Ye=function(t){return l(t,217).kf()},I(ev,"StripContainerCell/lambda$1$Type",1692),D(1693,1,ti,ja),h.Mb=function(t){return uun(l(t,217))},I(ev,"StripContainerCell/lambda$2$Type",1693),D(1694,1,{},Ou),h.Ye=function(t){return l(t,217).jf()},I(ev,"StripContainerCell/lambda$3$Type",1694),D(472,22,{3:1,34:1,22:1,472:1},bse);var w0,Fb,a1,X6t=Fr(ev,"VerticalLabelAlignment",472,Hr,N2n,u0n),Q6t;D(800,1,{},zke),h.c=0,h.d=0,h.k=0,h.s=0,h.t=0,h.v=!1,h.w=0,h.D=!1,I(tG,"NodeContext",800),D(1536,1,ii,Sa),h.Ne=function(t,n){return tnt(l(t,64),l(n,64))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(tG,"NodeContext/0methodref$comparePortSides$Type",1536),D(1537,1,ii,Po),h.Ne=function(t,n){return Rxn(l(t,117),l(n,117))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(tG,"NodeContext/1methodref$comparePortContexts$Type",1537),D(164,22,{3:1,34:1,22:1,164:1},of);var J6t,Z6t,e7t,t7t,n7t,r7t,i7t,s7t,a7t,o7t,c7t,u7t,l7t,h7t,f7t,d7t,g7t,p7t,b7t,m7t,v7t,H0e,w7t=Fr(tG,"NodeLabelLocation",164,Hr,eue,l0n),y7t;D(117,1,{117:1},c2t),h.a=!1,I(tG,"PortContext",117),D(1541,1,fr,Fc),h.Cd=function(t){vZe(l(t,314))},I(DP,g3t,1541),D(1542,1,ti,xa),h.Mb=function(t){return!!l(t,117).c},I(DP,p3t,1542),D(1543,1,fr,Ba),h.Cd=function(t){vZe(l(t,117).c)},I(DP,"LabelPlacer/lambda$2$Type",1543);var q_e;D(1540,1,fr,ga),h.Cd=function(t){py(),zcn(l(t,117))},I(DP,"NodeLabelAndSizeUtilities/lambda$0$Type",1540),D(801,1,fr,v4e),h.Cd=function(t){tln(this.b,this.c,this.a,l(t,187))},h.a=!1,h.c=!1,I(DP,"NodeLabelCellCreator/lambda$0$Type",801),D(1539,1,fr,Die),h.Cd=function(t){Vcn(this.a,l(t,187))},I(DP,"PortContextCreator/lambda$0$Type",1539);var pK;D(1902,1,{},kh),I(uT,"GreedyRectangleStripOverlapRemover",1902),D(1903,1,ii,lu),h.Ne=function(t,n){return Ohn(l(t,226),l(n,226))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(uT,"GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type",1903),D(1849,1,{},zQe),h.a=5,h.e=0,I(uT,"RectangleStripOverlapRemover",1849),D(1850,1,ii,o5),h.Ne=function(t,n){return Nhn(l(t,226),l(n,226))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(uT,"RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type",1850),D(1852,1,ii,Wh),h.Ne=function(t,n){return Egn(l(t,226),l(n,226))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(uT,"RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type",1852),D(417,22,{3:1,34:1,22:1,417:1},uq);var rB,V0e,U0e,iB,x7t=Fr(uT,"RectangleStripOverlapRemover/OverlapRemovalDirection",417,Hr,Ybn,h0n),k7t;D(226,1,{226:1},Dae),I(uT,"RectangleStripOverlapRemover/RectangleNode",226),D(1851,1,fr,Iie),h.Cd=function(t){l7n(this.a,l(t,226))},I(uT,"RectangleStripOverlapRemover/lambda$1$Type",1851),D(1323,1,ii,od),h.Ne=function(t,n){return MLn(l(t,176),l(n,176))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Md,"PolyominoCompactor/CornerCasesGreaterThanRestComparator",1323),D(1326,1,{},Gd),h.Kb=function(t){return l(t,334).a},I(Md,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type",1326),D(1327,1,ti,cd),h.Mb=function(t){return l(t,332).a},I(Md,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type",1327),D(1328,1,ti,Kd),h.Mb=function(t){return l(t,332).a},I(Md,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type",1328),D(1321,1,ii,$g),h.Ne=function(t,n){return a_n(l(t,176),l(n,176))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Md,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator",1321),D(1324,1,{},as),h.Kb=function(t){return l(t,334).a},I(Md,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type",1324),D(781,1,ii,wn),h.Ne=function(t,n){return q3n(l(t,176),l(n,176))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Md,"PolyominoCompactor/MinNumOfExtensionsComparator",781),D(1319,1,ii,Zr),h.Ne=function(t,n){return Xwn(l(t,330),l(n,330))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Md,"PolyominoCompactor/MinPerimeterComparator",1319),D(1320,1,ii,Zi),h.Ne=function(t,n){return N6n(l(t,330),l(n,330))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Md,"PolyominoCompactor/MinPerimeterComparatorWithShape",1320),D(1322,1,ii,nu),h.Ne=function(t,n){return __n(l(t,176),l(n,176))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Md,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator",1322),D(1325,1,{},vu),h.Kb=function(t){return l(t,334).a},I(Md,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type",1325),D(782,1,{},L3e),h.Ve=function(t,n){return zbn(this,l(t,42),l(n,176))},I(Md,"SuccessorCombination",782),D(649,1,{},Dl),h.Ve=function(t,n){var r;return rEn((r=l(t,42),l(n,176),r))},I(Md,"SuccessorJitter",649),D(648,1,{},Yh),h.Ve=function(t,n){var r;return HCn((r=l(t,42),l(n,176),r))},I(Md,"SuccessorLineByLine",648),D(573,1,{},w1),h.Ve=function(t,n){var r;return rTn((r=l(t,42),l(n,176),r))},I(Md,"SuccessorManhattan",573),D(1344,1,{},$0),h.Ve=function(t,n){var r;return dCn((r=l(t,42),l(n,176),r))},I(Md,"SuccessorMaxNormWindingInMathPosSense",1344),D(409,1,{},E5),h.Ve=function(t,n){return u5e(this,t,n)},h.c=!1,h.d=!1,h.e=!1,h.f=!1,I(Md,"SuccessorQuadrantsGeneric",409),D(1345,1,{},Wi),h.Kb=function(t){return l(t,334).a},I(Md,"SuccessorQuadrantsGeneric/lambda$0$Type",1345),D(332,22,{3:1,34:1,22:1,332:1},lq),h.a=!1;var sB,aB,oB,cB,E7t=Fr(rG,kEe,332,Hr,Kbn,f0n),T7t;D(1317,1,{}),h.Ib=function(){var t,n,r,a,o,f;for(r=" ",t=pt(0),o=0;o=0?"b"+t+"["+Coe(this.a)+"]":"b["+Coe(this.a)+"]"):"b_"+fw(this)},I(OP,"FBendpoint",250),D(290,137,{3:1,290:1,96:1,137:1},jrt),h.Ib=function(){return Coe(this)},I(OP,"FEdge",290),D(235,137,{3:1,235:1,96:1,137:1},KH);var yOn=I(OP,"FGraph",235);D(454,309,{3:1,454:1,309:1,96:1,137:1},zct),h.Ib=function(){return this.b==null||this.b.length==0?"l["+Coe(this.a)+"]":"l_"+this.b},I(OP,"FLabel",454),D(153,309,{3:1,153:1,309:1,96:1,137:1},wnt),h.Ib=function(){return X5e(this)},h.a=0,I(OP,"FNode",153),D(2100,1,{}),h.vf=function(t){yke(this,t)},h.wf=function(){qdt(this)},h.d=0,I(DEe,"AbstractForceModel",2100),D(641,2100,{641:1},jft),h.uf=function(t,n){var r,a,o,f,g;return pvt(this.f,t,n),o=ma(Ja(n.d),t.d),g=b.Math.sqrt(o.a*o.a+o.b*o.b),a=b.Math.max(0,g-eA(t.e)/2-eA(n.e)/2),r=Qpt(this.e,t,n),r>0?f=-ygn(a,this.c)*r:f=Yhn(a,this.b)*l(Q(t,(b0(),qx)),17).a,md(o,f/g),o},h.vf=function(t){yke(this,t),this.a=l(Q(t,(b0(),xK)),17).a,this.c=ze(Ge(Q(t,kK))),this.b=ze(Ge(Q(t,J0e)))},h.xf=function(t){return t0&&(f-=iun(a,this.a)*r),md(o,f*this.b/g),o},h.vf=function(t){var n,r,a,o,f,g,w;for(yke(this,t),this.b=ze(Ge(Q(t,(b0(),Z0e)))),this.c=this.b/l(Q(t,xK),17).a,a=t.e.c.length,f=0,o=0,w=new G(t.e);w.a0},h.a=0,h.b=0,h.c=0,I(DEe,"FruchtermanReingoldModel",642),D(860,1,Pf,KS),h.hf=function(t){sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,aG),""),"Force Model"),"Determines the model for force calculation."),Q_e),(g2(),ps)),J_e),un((r1(),Pn))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,IEe),""),"Iterations"),"The number of iterations on the force model."),pt(300)),Tc),ro),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,OEe),""),"Repulsive Power"),"Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model"),pt(0)),Tc),ro),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Dhe),""),"FR Temperature"),"The temperature is used as a scaling factor for particle displacements."),Dd),fo),ta),un(Pn)))),Qs(t,Dhe,aG,V7t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Ihe),""),"Eades Repulsion"),"Factor for repulsive forces in Eades' model."),5),fo),ta),un(Pn)))),Qs(t,Ihe,aG,z7t),rwt((new WS,t))};var R7t,j7t,Q_e,$7t,z7t,q7t,H7t,V7t;I(uL,"ForceMetaDataProvider",860),D(432,22,{3:1,34:1,22:1,432:1},D3e);var Q0e,yK,J_e=Fr(uL,"ForceModelStrategy",432,Hr,zpn,p0n),U7t;D(b2,1,Pf,WS),h.hf=function(t){rwt(t)};var G7t,K7t,Z_e,xK,eAe,W7t,Y7t,X7t,Q7t,tAe,J7t,nAe,rAe,Z7t,qx,e8t,J0e,iAe,t8t,n8t,kK,Z0e,r8t,i8t,s8t,sAe,a8t;I(uL,"ForceOptions",b2),D(1001,1,{},ld),h.sf=function(){var t;return t=new Dwe,t},h.tf=function(t){},I(uL,"ForceOptions/ForceFactory",1001);var hB,$L,Hx,EK;D(861,1,Pf,rz),h.hf=function(t){sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,PEe),""),"Fixed Position"),"Prevent that the node is moved by the layout algorithm."),(Hn(),!1)),(g2(),ya)),Ns),un((r1(),ha))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,BEe),""),"Desired Edge Length"),"Either specified for parent nodes or for individual edges, where the latter takes higher precedence."),100),fo),ta),rs(Pn,he(le(xg,1),it,170,0,[zd]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,FEe),""),"Layout Dimension"),"Dimensions that are permitted to be altered during layout."),aAe),ps),dAe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,REe),""),"Stress Epsilon"),"Termination criterion for the iterative process."),Dd),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,jEe),""),"Iteration Limit"),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),pt(Ii)),Tc),ro),un(Pn)))),Dvt((new iz,t))};var o8t,c8t,aAe,u8t,l8t,h8t;I(uL,"StressMetaDataProvider",861),D(1004,1,Pf,iz),h.hf=function(t){Dvt(t)};var TK,oAe,cAe,uAe,lAe,hAe,f8t,d8t,g8t,p8t,fAe,b8t;I(uL,"StressOptions",1004),D(1005,1,{},y1),h.sf=function(){var t;return t=new $rt,t},h.tf=function(t){},I(uL,"StressOptions/StressFactory",1005),D(1110,205,tv,$rt),h.rf=function(t,n){var r,a,o,f,g;for(n.Ug(A3t,1),Rt(Bt(at(t,(VN(),lAe))))?Rt(Bt(at(t,fAe)))||KO((r=new Yv((aw(),new Jv(t))),r)):W2t(new Dwe,t,n.eh(1)),o=u0t(t),a=$mt(this.a,o),g=a.Kc();g.Ob();)f=l(g.Pb(),235),!(f.e.c.length<=1)&&(_Ln(this.b,f),JEn(this.b),Vu(f.d,new ud));o=ewt(a),lwt(o),n.Vg()},I(uG,"StressLayoutProvider",1110),D(1111,1,fr,ud),h.Cd=function(t){Ake(l(t,454))},I(uG,"StressLayoutProvider/lambda$0$Type",1111),D(1002,1,{},BQe),h.c=0,h.e=0,h.g=0,I(uG,"StressMajorization",1002),D(391,22,{3:1,34:1,22:1,391:1},mse);var e1e,t1e,n1e,dAe=Fr(uG,"StressMajorization/Dimension",391,Hr,F2n,b0n),m8t;D(1003,1,ii,Dz),h.Ne=function(t,n){return Vfn(this.a,l(t,153),l(n,153))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(uG,"StressMajorization/lambda$0$Type",1003),D(1192,1,{},Got),I(Bx,"ElkLayered",1192),D(1193,1,fr,Iz),h.Cd=function(t){_kn(this.a,l(t,36))},I(Bx,"ElkLayered/lambda$0$Type",1193),D(1194,1,fr,Oie),h.Cd=function(t){Ufn(this.a,l(t,36))},I(Bx,"ElkLayered/lambda$1$Type",1194),D(1281,1,{},Lnt);var v8t,w8t,y8t;I(Bx,"GraphConfigurator",1281),D(770,1,fr,qp),h.Cd=function(t){tpt(this.a,l(t,10))},I(Bx,"GraphConfigurator/lambda$0$Type",770),D(771,1,{},u5),h.Kb=function(t){return mxe(),new bn(null,new kn(l(t,30).a,16))},I(Bx,"GraphConfigurator/lambda$1$Type",771),D(772,1,fr,n_),h.Cd=function(t){tpt(this.a,l(t,10))},I(Bx,"GraphConfigurator/lambda$2$Type",772),D(1109,205,tv,qQe),h.rf=function(t,n){var r;r=oLn(new VQe,t),qe(at(t,(Nt(),p4)))===qe((rp(),A2))?j4n(this.a,r,n):WEn(this.a,r,n),n.$g()||Kvt(new b8,r)},I(Bx,"LayeredLayoutProvider",1109),D(367,22,{3:1,34:1,22:1,367:1},oO);var y0,vg,bu,_u,mc,gAe=Fr(Bx,"LayeredPhases",367,Hr,zmn,m0n),x8t;D(1717,1,{},rft),h.i=0;var k8t;I(jP,"ComponentsToCGraphTransformer",1717);var E8t;D(1718,1,{},mm),h.yf=function(t,n){return b.Math.min(t.a!=null?ze(t.a):t.c.i,n.a!=null?ze(n.a):n.c.i)},h.zf=function(t,n){return b.Math.min(t.a!=null?ze(t.a):t.c.i,n.a!=null?ze(n.a):n.c.i)},I(jP,"ComponentsToCGraphTransformer/1",1718),D(86,1,{86:1}),h.i=0,h.k=!0,h.o=ia;var r1e=I(dL,"CNode",86);D(470,86,{470:1,86:1},Pye,U8e),h.Ib=function(){return""},I(jP,"ComponentsToCGraphTransformer/CRectNode",470),D(1688,1,{},q9);var i1e,s1e;I(jP,"OneDimensionalComponentsCompaction",1688),D(1689,1,{},Vv),h.Kb=function(t){return A2n(l(t,42))},h.Fb=function(t){return this===t},I(jP,"OneDimensionalComponentsCompaction/lambda$0$Type",1689),D(1690,1,{},Y7),h.Kb=function(t){return z4n(l(t,42))},h.Fb=function(t){return this===t},I(jP,"OneDimensionalComponentsCompaction/lambda$1$Type",1690),D(1720,1,{},Zst),I(dL,"CGraph",1720),D(194,1,{194:1},Qce),h.b=0,h.c=0,h.e=0,h.g=!0,h.i=ia,I(dL,"CGroup",194),D(1719,1,{},G2),h.yf=function(t,n){return b.Math.max(t.a!=null?ze(t.a):t.c.i,n.a!=null?ze(n.a):n.c.i)},h.zf=function(t,n){return b.Math.max(t.a!=null?ze(t.a):t.c.i,n.a!=null?ze(n.a):n.c.i)},I(dL,t3t,1719),D(1721,1,{},Zpt),h.d=!1;var T8t,a1e=I(dL,i3t,1721);D(1722,1,{},X7),h.Kb=function(t){return v3e(),Hn(),l(l(t,42).a,86).d.e!=0},h.Fb=function(t){return this===t},I(dL,s3t,1722),D(833,1,{},G4e),h.a=!1,h.b=!1,h.c=!1,h.d=!1,I(dL,a3t,833),D(1898,1,{},pst),I(lG,o3t,1898);var fB=ks(rv,Zwt);D(1899,1,{382:1},Yat),h.bf=function(t){nSn(this,l(t,476))},I(lG,c3t,1899),D(Lb,1,ii,l5),h.Ne=function(t,n){return hpn(l(t,86),l(n,86))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(lG,u3t,Lb),D(476,1,{476:1},O3e),h.a=!1,I(lG,l3t,476),D(1901,1,ii,X3),h.Ne=function(t,n){return f8n(l(t,476),l(n,476))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(lG,h3t,1901),D(148,1,{148:1},Ik,L4e),h.Fb=function(t){var n;return t==null||xOn!=bh(t)?!1:(n=l(t,148),Jc(this.c,n.c)&&Jc(this.d,n.d))},h.Hb=function(){return MN(he(le(wa,1),Rn,1,5,[this.c,this.d]))},h.Ib=function(){return"("+this.c+Co+this.d+(this.a?"cx":"")+this.b+")"},h.a=!0,h.c=0,h.d=0;var xOn=I(rv,"Point",148);D(416,22,{3:1,34:1,22:1,416:1},fq);var s3,a4,M6,o4,C8t=Fr(rv,"Point/Quadrant",416,Hr,Xbn,v0n),S8t;D(1708,1,{},$Qe),h.b=null,h.c=null,h.d=null,h.e=null,h.f=null;var _8t,A8t,L8t,M8t,D8t;I(rv,"RectilinearConvexHull",1708),D(583,1,{382:1},nU),h.bf=function(t){$vn(this,l(t,148))},h.b=0;var pAe;I(rv,"RectilinearConvexHull/MaximalElementsEventHandler",583),D(1710,1,ii,Fp),h.Ne=function(t,n){return fpn(Ge(t),Ge(n))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rv,"RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type",1710),D(1709,1,{382:1},wht),h.bf=function(t){mCn(this,l(t,148))},h.a=0,h.b=null,h.c=null,h.d=null,h.e=null,I(rv,"RectilinearConvexHull/RectangleEventHandler",1709),D(1711,1,ii,nI),h.Ne=function(t,n){return ybn(l(t,148),l(n,148))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rv,"RectilinearConvexHull/lambda$0$Type",1711),D(1712,1,ii,$J),h.Ne=function(t,n){return xbn(l(t,148),l(n,148))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rv,"RectilinearConvexHull/lambda$1$Type",1712),D(1713,1,ii,vm),h.Ne=function(t,n){return wbn(l(t,148),l(n,148))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rv,"RectilinearConvexHull/lambda$2$Type",1713),D(1714,1,ii,hu),h.Ne=function(t,n){return kbn(l(t,148),l(n,148))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rv,"RectilinearConvexHull/lambda$3$Type",1714),D(1715,1,ii,zJ),h.Ne=function(t,n){return Zxn(l(t,148),l(n,148))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rv,"RectilinearConvexHull/lambda$4$Type",1715),D(1716,1,{},Tot),I(rv,"Scanline",1716),D(2104,1,{}),I(V1,"AbstractGraphPlacer",2104),D(335,1,{335:1},hrt),h.Ff=function(t){return this.Gf(t)?(xn(this.b,l(Q(t,(ft(),pp)),21),t),!0):!1},h.Gf=function(t){var n,r,a,o;for(n=l(Q(t,(ft(),pp)),21),o=l($i(Xi,n),21),a=o.Kc();a.Ob();)if(r=l(a.Pb(),21),!l($i(this.b,r),15).dc())return!1;return!0};var Xi;I(V1,"ComponentGroup",335),D(779,2104,{},Nwe),h.Hf=function(t){var n,r;for(r=new G(this.a);r.ar&&(L=0,B+=w+a,w=0),E=f.c,KE(f,L+E.a,B+E.b),Y0(E),o=b.Math.max(o,L+C.a),w=b.Math.max(w,C.b),L+=C.a+a;n.f.a=o,n.f.b=B+w},h.Jf=function(t,n){var r,a,o,f,g;if(qe(Q(n,(Nt(),g4)))===qe((Km(),c4))){for(a=t.Kc();a.Ob();){for(r=l(a.Pb(),36),g=0,f=new G(r.a);f.ar&&!l(Q(f,(ft(),pp)),21).Hc((Ct(),Qn))||E&&l(Q(E,(ft(),pp)),21).Hc((Ct(),ar))||l(Q(f,(ft(),pp)),21).Hc((Ct(),er)))&&(z=B,V+=w+a,w=0),C=f.c,l(Q(f,(ft(),pp)),21).Hc((Ct(),Qn))&&(z=o+a),KE(f,z+C.a,V+C.b),o=b.Math.max(o,z+L.a),l(Q(f,pp),21).Hc(Dr)&&(B=b.Math.max(B,z+L.a+a)),Y0(C),w=b.Math.max(w,L.b),z+=L.a+a,E=f;n.f.a=o,n.f.b=V+w},h.Jf=function(t,n){},I(V1,"ModelOrderRowGraphPlacer",1313),D(1311,1,ii,cj),h.Ne=function(t,n){return j3n(l(t,36),l(n,36))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(V1,"SimpleRowGraphPlacer/1",1311);var O8t;D(1280,1,Ld,q0),h.Lb=function(t){var n;return n=l(Q(l(t,249).b,(Nt(),cc)),75),!!n&&n.b!=0},h.Fb=function(t){return this===t},h.Mb=function(t){var n;return n=l(Q(l(t,249).b,(Nt(),cc)),75),!!n&&n.b!=0},I(hG,"CompoundGraphPostprocessor/1",1280),D(1279,1,ts,UQe),h.Kf=function(t,n){kdt(this,l(t,36),n)},I(hG,"CompoundGraphPreprocessor",1279),D(453,1,{453:1},f1t),h.c=!1,I(hG,"CompoundGraphPreprocessor/ExternalPort",453),D(249,1,{249:1},Kq),h.Ib=function(){return aae(this.c)+":"+Kpt(this.b)},I(hG,"CrossHierarchyEdge",249),D(777,1,ii,GI),h.Ne=function(t,n){return $7n(this,l(t,249),l(n,249))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(hG,"CrossHierarchyEdgeComparator",777),D(305,137,{3:1,305:1,96:1,137:1}),h.p=0,I(Cu,"LGraphElement",305),D(18,305,{3:1,18:1,305:1,96:1,137:1},Tw),h.Ib=function(){return Kpt(this)};var u1e=I(Cu,"LEdge",18);D(36,305,{3:1,20:1,36:1,305:1,96:1,137:1},o7e),h.Jc=function(t){to(this,t)},h.Kc=function(){return new G(this.b)},h.Ib=function(){return this.b.c.length==0?"G-unlayered"+Tb(this.a):this.a.c.length==0?"G-layered"+Tb(this.b):"G[layerless"+Tb(this.a)+", layers"+Tb(this.b)+"]"};var N8t=I(Cu,"LGraph",36),P8t;D(666,1,{}),h.Lf=function(){return this.e.n},h.of=function(t){return Q(this.e,t)},h.Mf=function(){return this.e.o},h.Nf=function(){return this.e.p},h.pf=function(t){return ns(this.e,t)},h.Of=function(t){this.e.n.a=t.a,this.e.n.b=t.b},h.Pf=function(t){this.e.o.a=t.a,this.e.o.b=t.b},h.Qf=function(t){this.e.p=t},I(Cu,"LGraphAdapters/AbstractLShapeAdapter",666),D(474,1,{853:1},Tm),h.Rf=function(){var t,n;if(!this.b)for(this.b=eg(this.a.b.c.length),n=new G(this.a.b);n.a0&&H0t((Xn(n-1,t.length),t.charCodeAt(n-1)),N3t);)--n;if(f> ",t),fU(r)),hi(wu((t.a+="[",t),r.i),"]")),t.a},h.c=!0,h.d=!1;var yAe,xAe,kAe,EAe,TAe,CAe,F8t=I(Cu,"LPort",12);D(408,1,hg,T5),h.Jc=function(t){to(this,t)},h.Kc=function(){var t;return t=new G(this.a.e),new jWe(t)},I(Cu,"LPort/1",408),D(1309,1,Oa,jWe),h.Nb=function(t){Za(this,t)},h.Pb=function(){return l(re(this.a),18).c},h.Ob=function(){return Lc(this.a)},h.Qb=function(){Q_(this.a)},I(Cu,"LPort/1/1",1309),D(369,1,hg,C8),h.Jc=function(t){to(this,t)},h.Kc=function(){var t;return t=new G(this.a.g),new vwe(t)},I(Cu,"LPort/2",369),D(776,1,Oa,vwe),h.Nb=function(t){Za(this,t)},h.Pb=function(){return l(re(this.a),18).d},h.Ob=function(){return Lc(this.a)},h.Qb=function(){Q_(this.a)},I(Cu,"LPort/2/1",776),D(1302,1,hg,Met),h.Jc=function(t){to(this,t)},h.Kc=function(){return new N1(this)},I(Cu,"LPort/CombineIter",1302),D(208,1,Oa,N1),h.Nb=function(t){Za(this,t)},h.Qb=function(){aZe()},h.Ob=function(){return $_(this)},h.Pb=function(){return Lc(this.a)?re(this.a):re(this.b)},I(Cu,"LPort/CombineIter/1",208),D(1303,1,Ld,K2),h.Lb=function(t){return Lst(t)},h.Fb=function(t){return this===t},h.Mb=function(t){return kl(),l(t,12).g.c.length!=0},I(Cu,"LPort/lambda$0$Type",1303),D(1304,1,Ld,J3),h.Lb=function(t){return Mst(t)},h.Fb=function(t){return this===t},h.Mb=function(t){return kl(),l(t,12).e.c.length!=0},I(Cu,"LPort/lambda$1$Type",1304),D(1305,1,Ld,HJ),h.Lb=function(t){return kl(),l(t,12).j==(Ct(),Qn)},h.Fb=function(t){return this===t},h.Mb=function(t){return kl(),l(t,12).j==(Ct(),Qn)},I(Cu,"LPort/lambda$2$Type",1305),D(1306,1,Ld,wm),h.Lb=function(t){return kl(),l(t,12).j==(Ct(),ar)},h.Fb=function(t){return this===t},h.Mb=function(t){return kl(),l(t,12).j==(Ct(),ar)},I(Cu,"LPort/lambda$3$Type",1306),D(1307,1,Ld,VJ),h.Lb=function(t){return kl(),l(t,12).j==(Ct(),Dr)},h.Fb=function(t){return this===t},h.Mb=function(t){return kl(),l(t,12).j==(Ct(),Dr)},I(Cu,"LPort/lambda$4$Type",1307),D(1308,1,Ld,UJ),h.Lb=function(t){return kl(),l(t,12).j==(Ct(),er)},h.Fb=function(t){return this===t},h.Mb=function(t){return kl(),l(t,12).j==(Ct(),er)},I(Cu,"LPort/lambda$5$Type",1308),D(30,305,{3:1,20:1,305:1,30:1,96:1,137:1},yu),h.Jc=function(t){to(this,t)},h.Kc=function(){return new G(this.a)},h.Ib=function(){return"L_"+gc(this.b.b,this,0)+Tb(this.a)},I(Cu,"Layer",30),D(1330,1,{},VQe),I(v2,R3t,1330),D(1334,1,{},Q7),h.Kb=function(t){return bc(l(t,84))},I(v2,"ElkGraphImporter/0methodref$connectableShapeToNode$Type",1334),D(1337,1,{},uS),h.Kb=function(t){return bc(l(t,84))},I(v2,"ElkGraphImporter/1methodref$connectableShapeToNode$Type",1337),D(1331,1,fr,$We),h.Cd=function(t){l2t(this.a,l(t,123))},I(v2,MEe,1331),D(1332,1,fr,zWe),h.Cd=function(t){l2t(this.a,l(t,123))},I(v2,j3t,1332),D(1333,1,{},lj),h.Kb=function(t){return new bn(null,new kn(A5e(l(t,74)),16))},I(v2,$3t,1333),D(1335,1,ti,qWe),h.Mb=function(t){return Hln(this.a,l(t,27))},I(v2,z3t,1335),D(1336,1,{},H9),h.Kb=function(t){return new bn(null,new kn(apn(l(t,74)),16))},I(v2,"ElkGraphImporter/lambda$5$Type",1336),D(1338,1,ti,HWe),h.Mb=function(t){return Vln(this.a,l(t,27))},I(v2,"ElkGraphImporter/lambda$7$Type",1338),D(1339,1,ti,GJ),h.Mb=function(t){return ypn(l(t,74))},I(v2,"ElkGraphImporter/lambda$8$Type",1339),D(1297,1,{},b8);var R8t;I(v2,"ElkGraphLayoutTransferrer",1297),D(1298,1,ti,VWe),h.Mb=function(t){return Ifn(this.a,l(t,18))},I(v2,"ElkGraphLayoutTransferrer/lambda$0$Type",1298),D(1299,1,fr,UWe),h.Cd=function(t){sO(),vt(this.a,l(t,18))},I(v2,"ElkGraphLayoutTransferrer/lambda$1$Type",1299),D(1300,1,ti,GWe),h.Mb=function(t){return mfn(this.a,l(t,18))},I(v2,"ElkGraphLayoutTransferrer/lambda$2$Type",1300),D(1301,1,fr,KWe),h.Cd=function(t){sO(),vt(this.a,l(t,18))},I(v2,"ElkGraphLayoutTransferrer/lambda$3$Type",1301),D(819,1,{},i4e),I(rr,"BiLinkedHashMultiMap",819),D(1550,1,ts,V9),h.Kf=function(t,n){s3n(l(t,36),n)},I(rr,"CommentNodeMarginCalculator",1550),D(1551,1,{},KJ),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"CommentNodeMarginCalculator/lambda$0$Type",1551),D(1552,1,fr,WJ),h.Cd=function(t){sLn(l(t,10))},I(rr,"CommentNodeMarginCalculator/lambda$1$Type",1552),D(1553,1,ts,YJ),h.Kf=function(t,n){uSn(l(t,36),n)},I(rr,"CommentPostprocessor",1553),D(1554,1,ts,XJ),h.Kf=function(t,n){DDn(l(t,36),n)},I(rr,"CommentPreprocessor",1554),D(1555,1,ts,QJ),h.Kf=function(t,n){SCn(l(t,36),n)},I(rr,"ConstraintsPostprocessor",1555),D(1556,1,ts,JJ),h.Kf=function(t,n){O3n(l(t,36),n)},I(rr,"EdgeAndLayerConstraintEdgeReverser",1556),D(1557,1,ts,ZJ),h.Kf=function(t,n){E5n(l(t,36),n)},I(rr,"EndLabelPostprocessor",1557),D(1558,1,{},eZ),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"EndLabelPostprocessor/lambda$0$Type",1558),D(1559,1,ti,tZ),h.Mb=function(t){return Rmn(l(t,10))},I(rr,"EndLabelPostprocessor/lambda$1$Type",1559),D(1560,1,fr,nZ),h.Cd=function(t){d8n(l(t,10))},I(rr,"EndLabelPostprocessor/lambda$2$Type",1560),D(1561,1,ts,rZ),h.Kf=function(t,n){tkn(l(t,36),n)},I(rr,"EndLabelPreprocessor",1561),D(1562,1,{},rI),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"EndLabelPreprocessor/lambda$0$Type",1562),D(1563,1,fr,mit),h.Cd=function(t){nln(this.a,this.b,this.c,l(t,10))},h.a=0,h.b=0,h.c=!1,I(rr,"EndLabelPreprocessor/lambda$1$Type",1563),D(1564,1,ti,iZ),h.Mb=function(t){return qe(Q(l(t,72),(Nt(),jd)))===qe((F1(),rC))},I(rr,"EndLabelPreprocessor/lambda$2$Type",1564),D(1565,1,fr,WWe),h.Cd=function(t){ui(this.a,l(t,72))},I(rr,"EndLabelPreprocessor/lambda$3$Type",1565),D(1566,1,ti,sZ),h.Mb=function(t){return qe(Q(l(t,72),(Nt(),jd)))===qe((F1(),_4))},I(rr,"EndLabelPreprocessor/lambda$4$Type",1566),D(1567,1,fr,YWe),h.Cd=function(t){ui(this.a,l(t,72))},I(rr,"EndLabelPreprocessor/lambda$5$Type",1567),D(1615,1,ts,Hre),h.Kf=function(t,n){k4n(l(t,36),n)};var j8t;I(rr,"EndLabelSorter",1615),D(1616,1,ii,lS),h.Ne=function(t,n){return t6n(l(t,466),l(n,466))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"EndLabelSorter/1",1616),D(466,1,{466:1},Hat),I(rr,"EndLabelSorter/LabelGroup",466),D(1617,1,{},hj),h.Kb=function(t){return iO(),new bn(null,new kn(l(t,30).a,16))},I(rr,"EndLabelSorter/lambda$0$Type",1617),D(1618,1,ti,J7),h.Mb=function(t){return iO(),l(t,10).k==(Zn(),Ps)},I(rr,"EndLabelSorter/lambda$1$Type",1618),D(1619,1,fr,aZ),h.Cd=function(t){p9n(l(t,10))},I(rr,"EndLabelSorter/lambda$2$Type",1619),D(1620,1,ti,oZ),h.Mb=function(t){return iO(),qe(Q(l(t,72),(Nt(),jd)))===qe((F1(),_4))},I(rr,"EndLabelSorter/lambda$3$Type",1620),D(1621,1,ti,cZ),h.Mb=function(t){return iO(),qe(Q(l(t,72),(Nt(),jd)))===qe((F1(),rC))},I(rr,"EndLabelSorter/lambda$4$Type",1621),D(1568,1,ts,uZ),h.Kf=function(t,n){yLn(this,l(t,36))},h.b=0,h.c=0,I(rr,"FinalSplineBendpointsCalculator",1568),D(1569,1,{},lZ),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"FinalSplineBendpointsCalculator/lambda$0$Type",1569),D(1570,1,{},hS),h.Kb=function(t){return new bn(null,new vw(new hr(dr(qs(l(t,10)).a.Kc(),new j))))},I(rr,"FinalSplineBendpointsCalculator/lambda$1$Type",1570),D(1571,1,ti,iI),h.Mb=function(t){return!Do(l(t,18))},I(rr,"FinalSplineBendpointsCalculator/lambda$2$Type",1571),D(1572,1,ti,fj),h.Mb=function(t){return ns(l(t,18),(ft(),fv))},I(rr,"FinalSplineBendpointsCalculator/lambda$3$Type",1572),D(1573,1,fr,XWe),h.Cd=function(t){L_n(this.a,l(t,131))},I(rr,"FinalSplineBendpointsCalculator/lambda$4$Type",1573),D(1574,1,fr,h5),h.Cd=function(t){JN(l(t,18).a)},I(rr,"FinalSplineBendpointsCalculator/lambda$5$Type",1574),D(803,1,ts,wwe),h.Kf=function(t,n){dMn(this,l(t,36),n)},I(rr,"GraphTransformer",803),D(517,22,{3:1,34:1,22:1,517:1},I3e);var h1e,dB,$8t=Fr(rr,"GraphTransformer/Mode",517,Hr,qpn,E1n),z8t;D(1575,1,ts,f5),h.Kf=function(t,n){PTn(l(t,36),n)},I(rr,"HierarchicalNodeResizingProcessor",1575),D(1576,1,ts,hZ),h.Kf=function(t,n){e3n(l(t,36),n)},I(rr,"HierarchicalPortConstraintProcessor",1576),D(1577,1,ii,t0),h.Ne=function(t,n){return k6n(l(t,10),l(n,10))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"HierarchicalPortConstraintProcessor/NodeComparator",1577),D(1578,1,ts,Z7),h.Kf=function(t,n){EAn(l(t,36),n)},I(rr,"HierarchicalPortDummySizeProcessor",1578),D(1579,1,ts,fZ),h.Kf=function(t,n){OSn(this,l(t,36),n)},h.a=0,I(rr,"HierarchicalPortOrthogonalEdgeRouter",1579),D(1580,1,ii,U9),h.Ne=function(t,n){return Phn(l(t,10),l(n,10))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"HierarchicalPortOrthogonalEdgeRouter/1",1580),D(1581,1,ii,Wd),h.Ne=function(t,n){return zvn(l(t,10),l(n,10))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"HierarchicalPortOrthogonalEdgeRouter/2",1581),D(1582,1,ts,dZ),h.Kf=function(t,n){Xxn(l(t,36),n)},I(rr,"HierarchicalPortPositionProcessor",1582),D(1583,1,ts,Kv),h.Kf=function(t,n){fIn(this,l(t,36))},h.a=0,h.c=0;var CK,SK;I(rr,"HighDegreeNodeLayeringProcessor",1583),D(580,1,{580:1},gZ),h.b=-1,h.d=-1,I(rr,"HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation",580),D(1584,1,{},pZ),h.Kb=function(t){return OO(),ka(l(t,10))},h.Fb=function(t){return this===t},I(rr,"HighDegreeNodeLayeringProcessor/lambda$0$Type",1584),D(1585,1,{},dj),h.Kb=function(t){return OO(),qs(l(t,10))},h.Fb=function(t){return this===t},I(rr,"HighDegreeNodeLayeringProcessor/lambda$1$Type",1585),D(1591,1,ts,bZ),h.Kf=function(t,n){pAn(this,l(t,36),n)},I(rr,"HyperedgeDummyMerger",1591),D(804,1,{},w4e),h.a=!1,h.b=!1,h.c=!1,I(rr,"HyperedgeDummyMerger/MergeState",804),D(1592,1,{},fS),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"HyperedgeDummyMerger/lambda$0$Type",1592),D(1593,1,{},dS),h.Kb=function(t){return new bn(null,new kn(l(t,10).j,16))},I(rr,"HyperedgeDummyMerger/lambda$1$Type",1593),D(1594,1,fr,gj),h.Cd=function(t){l(t,12).p=-1},I(rr,"HyperedgeDummyMerger/lambda$2$Type",1594),D(1595,1,ts,sI),h.Kf=function(t,n){dAn(l(t,36),n)},I(rr,"HypernodesProcessor",1595),D(1596,1,ts,e8),h.Kf=function(t,n){kAn(l(t,36),n)},I(rr,"InLayerConstraintProcessor",1596),D(1597,1,ts,mZ),h.Kf=function(t,n){p3n(l(t,36),n)},I(rr,"InnermostNodeMarginCalculator",1597),D(1598,1,ts,pj),h.Kf=function(t,n){_Dn(this,l(t,36))},h.a=ia,h.b=ia,h.c=gs,h.d=gs;var kOn=I(rr,"InteractiveExternalPortPositioner",1598);D(1599,1,{},bj),h.Kb=function(t){return l(t,18).d.i},h.Fb=function(t){return this===t},I(rr,"InteractiveExternalPortPositioner/lambda$0$Type",1599),D(1600,1,{},QWe),h.Kb=function(t){return Bhn(this.a,Ge(t))},h.Fb=function(t){return this===t},I(rr,"InteractiveExternalPortPositioner/lambda$1$Type",1600),D(1601,1,{},vZ),h.Kb=function(t){return l(t,18).c.i},h.Fb=function(t){return this===t},I(rr,"InteractiveExternalPortPositioner/lambda$2$Type",1601),D(1602,1,{},JWe),h.Kb=function(t){return Fhn(this.a,Ge(t))},h.Fb=function(t){return this===t},I(rr,"InteractiveExternalPortPositioner/lambda$3$Type",1602),D(1603,1,{},ZWe),h.Kb=function(t){return Nfn(this.a,Ge(t))},h.Fb=function(t){return this===t},I(rr,"InteractiveExternalPortPositioner/lambda$4$Type",1603),D(1604,1,{},eYe),h.Kb=function(t){return Pfn(this.a,Ge(t))},h.Fb=function(t){return this===t},I(rr,"InteractiveExternalPortPositioner/lambda$5$Type",1604),D(81,22,{3:1,34:1,22:1,81:1,196:1},Ws),h.dg=function(){switch(this.g){case 15:return new Uj;case 22:return new Dee;case 47:return new Nee;case 28:case 35:return new CZ;case 32:return new V9;case 42:return new YJ;case 1:return new XJ;case 41:return new QJ;case 56:return new wwe((dE(),dB));case 0:return new wwe((dE(),h1e));case 2:return new JJ;case 54:return new ZJ;case 33:return new rZ;case 51:return new uZ;case 55:return new f5;case 13:return new hZ;case 38:return new Z7;case 44:return new fZ;case 40:return new dZ;case 9:return new Kv;case 49:return new nrt;case 37:return new bZ;case 43:return new sI;case 27:return new e8;case 30:return new mZ;case 3:return new pj;case 18:return new yZ;case 29:return new xZ;case 5:return new fk;case 50:return new wZ;case 34:return new sz;case 36:return new d5;case 52:return new Hre;case 11:return new G9;case 7:return new Vre;case 39:return new aI;case 45:return new Z3;case 16:return new K9;case 10:return new Wet;case 48:return new mj;case 21:return new oI;case 23:return new Wie((Iw(),oM));case 8:return new cI;case 12:return new _Z;case 4:return new uI;case 19:return new cz;case 17:return new IZ;case 53:return new OZ;case 6:return new Tj;case 25:return new KQe;case 46:return new FZ;case 31:return new Vrt;case 14:return new UZ;case 26:return new Fee;case 20:return new Aj;case 24:return new Wie((Iw(),MW));default:throw ue(new Yn(Fhe+(this.f!=null?this.f:""+this.g)))}};var SAe,_Ae,AAe,LAe,MAe,DAe,IAe,OAe,NAe,PAe,D6,_K,AK,BAe,FAe,RAe,jAe,$Ae,zAe,qAe,zL,HAe,VAe,UAe,GAe,KAe,f1e,LK,MK,WAe,DK,IK,OK,LT,u4,l4,YAe,NK,PK,XAe,BK,FK,QAe,JAe,ZAe,eLe,RK,d1e,gB,jK,$K,zK,qK,tLe,nLe,rLe,iLe,EOn=Fr(rr,Rhe,81,Hr,rbt,k0n),q8t;D(1605,1,ts,yZ),h.Kf=function(t,n){CDn(l(t,36),n)},I(rr,"InvertedPortProcessor",1605),D(1606,1,ts,xZ),h.Kf=function(t,n){x_n(l(t,36),n)},I(rr,"LabelAndNodeSizeProcessor",1606),D(1607,1,ti,kZ),h.Mb=function(t){return l(t,10).k==(Zn(),Ps)},I(rr,"LabelAndNodeSizeProcessor/lambda$0$Type",1607),D(1608,1,ti,EZ),h.Mb=function(t){return l(t,10).k==(Zn(),Us)},I(rr,"LabelAndNodeSizeProcessor/lambda$1$Type",1608),D(1609,1,fr,vit),h.Cd=function(t){rln(this.b,this.a,this.c,l(t,10))},h.a=!1,h.c=!1,I(rr,"LabelAndNodeSizeProcessor/lambda$2$Type",1609),D(1610,1,ts,fk),h.Kf=function(t,n){QMn(l(t,36),n)};var H8t;I(rr,"LabelDummyInserter",1610),D(1611,1,Ld,Yd),h.Lb=function(t){return qe(Q(l(t,72),(Nt(),jd)))===qe((F1(),nC))},h.Fb=function(t){return this===t},h.Mb=function(t){return qe(Q(l(t,72),(Nt(),jd)))===qe((F1(),nC))},I(rr,"LabelDummyInserter/1",1611),D(1612,1,ts,wZ),h.Kf=function(t,n){jMn(l(t,36),n)},I(rr,"LabelDummyRemover",1612),D(1613,1,ti,Uv),h.Mb=function(t){return Rt(Bt(Q(l(t,72),(Nt(),tde))))},I(rr,"LabelDummyRemover/lambda$0$Type",1613),D(1378,1,ts,sz),h.Kf=function(t,n){DMn(this,l(t,36),n)},h.a=null;var g1e;I(rr,"LabelDummySwitcher",1378),D(293,1,{293:1},nmt),h.c=0,h.d=null,h.f=0,I(rr,"LabelDummySwitcher/LabelDummyInfo",293),D(1379,1,{},TZ),h.Kb=function(t){return lx(),new bn(null,new kn(l(t,30).a,16))},I(rr,"LabelDummySwitcher/lambda$0$Type",1379),D(1380,1,ti,gS),h.Mb=function(t){return lx(),l(t,10).k==(Zn(),cu)},I(rr,"LabelDummySwitcher/lambda$1$Type",1380),D(1381,1,{},tYe),h.Kb=function(t){return vfn(this.a,l(t,10))},I(rr,"LabelDummySwitcher/lambda$2$Type",1381),D(1382,1,fr,nYe),h.Cd=function(t){Rgn(this.a,l(t,293))},I(rr,"LabelDummySwitcher/lambda$3$Type",1382),D(1383,1,ii,pS),h.Ne=function(t,n){return cgn(l(t,293),l(n,293))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"LabelDummySwitcher/lambda$4$Type",1383),D(802,1,ts,CZ),h.Kf=function(t,n){yvn(l(t,36),n)},I(rr,"LabelManagementProcessor",802),D(1614,1,ts,d5),h.Kf=function(t,n){QCn(l(t,36),n)},I(rr,"LabelSideSelector",1614),D(1622,1,ts,G9),h.Kf=function(t,n){RAn(l(t,36),n)},I(rr,"LayerConstraintPostprocessor",1622),D(1623,1,ts,Vre),h.Kf=function(t,n){OEn(l(t,36),n)};var sLe;I(rr,"LayerConstraintPreprocessor",1623),D(371,22,{3:1,34:1,22:1,371:1},gq);var pB,HK,VK,p1e,V8t=Fr(rr,"LayerConstraintPreprocessor/HiddenNodeConnections",371,Hr,Jbn,E0n),U8t;D(1624,1,ts,aI),h.Kf=function(t,n){tMn(l(t,36),n)},I(rr,"LayerSizeAndGraphHeightCalculator",1624),D(1625,1,ts,Z3),h.Kf=function(t,n){BTn(l(t,36),n)},I(rr,"LongEdgeJoiner",1625),D(1626,1,ts,K9),h.Kf=function(t,n){DLn(l(t,36),n)},I(rr,"LongEdgeSplitter",1626),D(1627,1,ts,Wet),h.Kf=function(t,n){fDn(this,l(t,36),n)},h.e=0,h.f=0,h.j=0,h.k=0,h.n=0,h.o=0;var G8t,K8t;I(rr,"NodePromotion",1627),D(1628,1,ii,SZ),h.Ne=function(t,n){return Cyn(l(t,10),l(n,10))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"NodePromotion/1",1628),D(1629,1,ii,bS),h.Ne=function(t,n){return Syn(l(t,10),l(n,10))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"NodePromotion/2",1629),D(1630,1,{},hd),h.Kb=function(t){return l(t,42),Yq(),Hn(),!0},h.Fb=function(t){return this===t},I(rr,"NodePromotion/lambda$0$Type",1630),D(1631,1,{},aYe),h.Kb=function(t){return x2n(this.a,l(t,42))},h.Fb=function(t){return this===t},h.a=0,I(rr,"NodePromotion/lambda$1$Type",1631),D(1632,1,{},oYe),h.Kb=function(t){return y2n(this.a,l(t,42))},h.Fb=function(t){return this===t},h.a=0,I(rr,"NodePromotion/lambda$2$Type",1632),D(1633,1,ts,mj),h.Kf=function(t,n){aIn(l(t,36),n)},I(rr,"NorthSouthPortPostprocessor",1633),D(1634,1,ts,oI),h.Kf=function(t,n){$Dn(l(t,36),n)},I(rr,"NorthSouthPortPreprocessor",1634),D(1635,1,ii,W9),h.Ne=function(t,n){return $3n(l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"NorthSouthPortPreprocessor/lambda$0$Type",1635),D(1636,1,ts,cI),h.Kf=function(t,n){nAn(l(t,36),n)},I(rr,"PartitionMidprocessor",1636),D(1637,1,ti,vj),h.Mb=function(t){return ns(l(t,10),(Nt(),HT))},I(rr,"PartitionMidprocessor/lambda$0$Type",1637),D(1638,1,fr,cYe),h.Cd=function(t){xpn(this.a,l(t,10))},I(rr,"PartitionMidprocessor/lambda$1$Type",1638),D(1639,1,ts,_Z),h.Kf=function(t,n){rCn(l(t,36),n)},I(rr,"PartitionPostprocessor",1639),D(1640,1,ts,uI),h.Kf=function(t,n){mEn(l(t,36),n)},I(rr,"PartitionPreprocessor",1640),D(1641,1,ti,AZ),h.Mb=function(t){return ns(l(t,10),(Nt(),HT))},I(rr,"PartitionPreprocessor/lambda$0$Type",1641),D(1642,1,{},LZ),h.Kb=function(t){return new bn(null,new vw(new hr(dr(qs(l(t,10)).a.Kc(),new j))))},I(rr,"PartitionPreprocessor/lambda$1$Type",1642),D(1643,1,ti,wj),h.Mb=function(t){return o6n(l(t,18))},I(rr,"PartitionPreprocessor/lambda$2$Type",1643),D(1644,1,fr,t8),h.Cd=function(t){ryn(l(t,18))},I(rr,"PartitionPreprocessor/lambda$3$Type",1644),D(1645,1,ts,cz),h.Kf=function(t,n){B_n(l(t,36),n)};var aLe,W8t,Y8t,X8t,oLe,cLe;I(rr,"PortListSorter",1645),D(1648,1,ii,yj),h.Ne=function(t,n){return Kct(l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"PortListSorter/lambda$0$Type",1648),D(1650,1,ii,n8),h.Ne=function(t,n){return Smt(l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"PortListSorter/lambda$1$Type",1650),D(1646,1,{},MZ),h.Kb=function(t){return TE(),l(t,12).e},I(rr,"PortListSorter/lambda$2$Type",1646),D(1647,1,{},lI),h.Kb=function(t){return TE(),l(t,12).g},I(rr,"PortListSorter/lambda$3$Type",1647),D(1649,1,ii,DZ),h.Ne=function(t,n){return D7n(l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"PortListSorter/lambda$4$Type",1649),D(1651,1,ts,IZ),h.Kf=function(t,n){GEn(l(t,36),n)},I(rr,"PortSideProcessor",1651),D(1652,1,ts,OZ),h.Kf=function(t,n){KSn(l(t,36),n)},I(rr,"ReversedEdgeRestorer",1652),D(1657,1,ts,KQe),h.Kf=function(t,n){d7n(this,l(t,36),n)},I(rr,"SelfLoopPortRestorer",1657),D(1658,1,{},NZ),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"SelfLoopPortRestorer/lambda$0$Type",1658),D(1659,1,ti,xj),h.Mb=function(t){return l(t,10).k==(Zn(),Ps)},I(rr,"SelfLoopPortRestorer/lambda$1$Type",1659),D(1660,1,ti,PZ),h.Mb=function(t){return ns(l(t,10),(ft(),h3))},I(rr,"SelfLoopPortRestorer/lambda$2$Type",1660),D(1661,1,{},BZ),h.Kb=function(t){return l(Q(l(t,10),(ft(),h3)),337)},I(rr,"SelfLoopPortRestorer/lambda$3$Type",1661),D(1662,1,fr,iYe),h.Cd=function(t){A9n(this.a,l(t,337))},I(rr,"SelfLoopPortRestorer/lambda$4$Type",1662),D(805,1,fr,kj),h.Cd=function(t){z9n(l(t,105))},I(rr,"SelfLoopPortRestorer/lambda$5$Type",805),D(1663,1,ts,FZ),h.Kf=function(t,n){w6n(l(t,36),n)},I(rr,"SelfLoopPostProcessor",1663),D(1664,1,{},RZ),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"SelfLoopPostProcessor/lambda$0$Type",1664),D(1665,1,ti,jZ),h.Mb=function(t){return l(t,10).k==(Zn(),Ps)},I(rr,"SelfLoopPostProcessor/lambda$1$Type",1665),D(1666,1,ti,$Z),h.Mb=function(t){return ns(l(t,10),(ft(),h3))},I(rr,"SelfLoopPostProcessor/lambda$2$Type",1666),D(1667,1,fr,Ej),h.Cd=function(t){M8n(l(t,10))},I(rr,"SelfLoopPostProcessor/lambda$3$Type",1667),D(1668,1,{},zZ),h.Kb=function(t){return new bn(null,new kn(l(t,105).f,1))},I(rr,"SelfLoopPostProcessor/lambda$4$Type",1668),D(1669,1,fr,rYe),h.Cd=function(t){nmn(this.a,l(t,340))},I(rr,"SelfLoopPostProcessor/lambda$5$Type",1669),D(1670,1,ti,qZ),h.Mb=function(t){return!!l(t,105).i},I(rr,"SelfLoopPostProcessor/lambda$6$Type",1670),D(1671,1,fr,sYe),h.Cd=function(t){nun(this.a,l(t,105))},I(rr,"SelfLoopPostProcessor/lambda$7$Type",1671),D(1653,1,ts,Tj),h.Kf=function(t,n){xTn(l(t,36),n)},I(rr,"SelfLoopPreProcessor",1653),D(1654,1,{},Cj),h.Kb=function(t){return new bn(null,new kn(l(t,105).f,1))},I(rr,"SelfLoopPreProcessor/lambda$0$Type",1654),D(1655,1,{},Sj),h.Kb=function(t){return l(t,340).a},I(rr,"SelfLoopPreProcessor/lambda$1$Type",1655),D(1656,1,fr,HZ),h.Cd=function(t){shn(l(t,18))},I(rr,"SelfLoopPreProcessor/lambda$2$Type",1656),D(1672,1,ts,Vrt),h.Kf=function(t,n){u9n(this,l(t,36),n)},I(rr,"SelfLoopRouter",1672),D(1673,1,{},VZ),h.Kb=function(t){return new bn(null,new kn(l(t,30).a,16))},I(rr,"SelfLoopRouter/lambda$0$Type",1673),D(1674,1,ti,Y9),h.Mb=function(t){return l(t,10).k==(Zn(),Ps)},I(rr,"SelfLoopRouter/lambda$1$Type",1674),D(1675,1,ti,r8),h.Mb=function(t){return ns(l(t,10),(ft(),h3))},I(rr,"SelfLoopRouter/lambda$2$Type",1675),D(1676,1,{},mS),h.Kb=function(t){return l(Q(l(t,10),(ft(),h3)),337)},I(rr,"SelfLoopRouter/lambda$3$Type",1676),D(1677,1,fr,Aet),h.Cd=function(t){ppn(this.a,this.b,l(t,337))},I(rr,"SelfLoopRouter/lambda$4$Type",1677),D(1678,1,ts,UZ),h.Kf=function(t,n){jCn(l(t,36),n)},I(rr,"SemiInteractiveCrossMinProcessor",1678),D(1679,1,ti,hI),h.Mb=function(t){return l(t,10).k==(Zn(),Ps)},I(rr,"SemiInteractiveCrossMinProcessor/lambda$0$Type",1679),D(1680,1,ti,vS),h.Mb=function(t){return ost(l(t,10))._b((Nt(),w4))},I(rr,"SemiInteractiveCrossMinProcessor/lambda$1$Type",1680),D(1681,1,ii,fI),h.Ne=function(t,n){return n3n(l(t,10),l(n,10))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(rr,"SemiInteractiveCrossMinProcessor/lambda$2$Type",1681),D(1682,1,{},_j),h.Ve=function(t,n){return kpn(l(t,10),l(n,10))},I(rr,"SemiInteractiveCrossMinProcessor/lambda$3$Type",1682),D(1684,1,ts,Aj),h.Kf=function(t,n){uLn(l(t,36),n)},I(rr,"SortByInputModelProcessor",1684),D(1685,1,ti,GZ),h.Mb=function(t){return l(t,12).g.c.length!=0},I(rr,"SortByInputModelProcessor/lambda$0$Type",1685),D(1686,1,fr,uYe),h.Cd=function(t){G9n(this.a,l(t,12))},I(rr,"SortByInputModelProcessor/lambda$1$Type",1686),D(1759,817,{},mft),h.df=function(t){var n,r,a,o;switch(this.c=t,this.a.g){case 2:n=new bt,Is(Fi(new bn(null,new kn(this.c.a.b,16)),new ree),new Fet(this,n)),ZN(this,new WZ),Vu(n,new Lj),n.c.length=0,Is(Fi(new bn(null,new kn(this.c.a.b,16)),new Mj),new hYe(n)),ZN(this,new YZ),Vu(n,new XZ),n.c.length=0,r=vnt(uce(xy(new bn(null,new kn(this.c.a.b,16)),new fYe(this))),new QZ),Is(new bn(null,new kn(this.c.a.a,16)),new Det(r,n)),ZN(this,new ZZ),Vu(n,new Dj),n.c.length=0;break;case 3:a=new bt,ZN(this,new KZ),o=vnt(uce(xy(new bn(null,new kn(this.c.a.b,16)),new lYe(this))),new JZ),Is(Fi(new bn(null,new kn(this.c.a.b,16)),new eee),new Oet(o,a)),ZN(this,new tee),Vu(a,new nee),a.c.length=0;break;default:throw ue(new NQe)}},h.b=0,I(aa,"EdgeAwareScanlineConstraintCalculation",1759),D(1760,1,Ld,KZ),h.Lb=function(t){return De(l(t,60).g,154)},h.Fb=function(t){return this===t},h.Mb=function(t){return De(l(t,60).g,154)},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$0$Type",1760),D(1761,1,{},lYe),h.Ye=function(t){return Lkn(this.a,l(t,60))},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$1$Type",1761),D(1769,1,QU,Let),h.de=function(){FA(this.a,this.b,-1)},h.b=0,I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$10$Type",1769),D(1771,1,Ld,WZ),h.Lb=function(t){return De(l(t,60).g,154)},h.Fb=function(t){return this===t},h.Mb=function(t){return De(l(t,60).g,154)},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$11$Type",1771),D(1772,1,fr,Lj),h.Cd=function(t){l(t,380).de()},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$12$Type",1772),D(1773,1,ti,Mj),h.Mb=function(t){return De(l(t,60).g,10)},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$13$Type",1773),D(1775,1,fr,hYe),h.Cd=function(t){Y4n(this.a,l(t,60))},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$14$Type",1775),D(1774,1,QU,Net),h.de=function(){FA(this.b,this.a,-1)},h.a=0,I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$15$Type",1774),D(1776,1,Ld,YZ),h.Lb=function(t){return De(l(t,60).g,10)},h.Fb=function(t){return this===t},h.Mb=function(t){return De(l(t,60).g,10)},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$16$Type",1776),D(1777,1,fr,XZ),h.Cd=function(t){l(t,380).de()},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$17$Type",1777),D(1778,1,{},fYe),h.Ye=function(t){return Mkn(this.a,l(t,60))},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$18$Type",1778),D(1779,1,{},QZ),h.We=function(){return 0},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$19$Type",1779),D(1762,1,{},JZ),h.We=function(){return 0},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$2$Type",1762),D(1781,1,fr,Det),h.Cd=function(t){egn(this.a,this.b,l(t,316))},h.a=0,I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$20$Type",1781),D(1780,1,QU,Iet),h.de=function(){I2t(this.a,this.b,-1)},h.b=0,I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$21$Type",1780),D(1782,1,Ld,ZZ),h.Lb=function(t){return l(t,60),!0},h.Fb=function(t){return this===t},h.Mb=function(t){return l(t,60),!0},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$22$Type",1782),D(1783,1,fr,Dj),h.Cd=function(t){l(t,380).de()},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$23$Type",1783),D(1763,1,ti,eee),h.Mb=function(t){return De(l(t,60).g,10)},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$3$Type",1763),D(1765,1,fr,Oet),h.Cd=function(t){tgn(this.a,this.b,l(t,60))},h.a=0,I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$4$Type",1765),D(1764,1,QU,Pet),h.de=function(){FA(this.b,this.a,-1)},h.a=0,I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$5$Type",1764),D(1766,1,Ld,tee),h.Lb=function(t){return l(t,60),!0},h.Fb=function(t){return this===t},h.Mb=function(t){return l(t,60),!0},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$6$Type",1766),D(1767,1,fr,nee),h.Cd=function(t){l(t,380).de()},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$7$Type",1767),D(1768,1,ti,ree),h.Mb=function(t){return De(l(t,60).g,154)},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$8$Type",1768),D(1770,1,fr,Fet),h.Cd=function(t){wwn(this.a,this.b,l(t,60))},I(aa,"EdgeAwareScanlineConstraintCalculation/lambda$9$Type",1770),D(1586,1,ts,nrt),h.Kf=function(t,n){FLn(this,l(t,36),n)};var Q8t;I(aa,"HorizontalGraphCompactor",1586),D(1587,1,{},dYe),h.ff=function(t,n){var r,a,o;return q6e(t,n)||(r=G5(t),a=G5(n),r&&r.k==(Zn(),Us)||a&&a.k==(Zn(),Us))?0:(o=l(Q(this.a.a,(ft(),$6)),312),zhn(o,r?r.k:(Zn(),Aa),a?a.k:(Zn(),Aa)))},h.gf=function(t,n){var r,a,o;return q6e(t,n)?1:(r=G5(t),a=G5(n),o=l(Q(this.a.a,(ft(),$6)),312),Oye(o,r?r.k:(Zn(),Aa),a?a.k:(Zn(),Aa)))},I(aa,"HorizontalGraphCompactor/1",1587),D(1588,1,{},Ij),h.ef=function(t,n){return p_(),t.a.i==0},I(aa,"HorizontalGraphCompactor/lambda$0$Type",1588),D(1589,1,{},gYe),h.ef=function(t,n){return Cpn(this.a,t,n)},I(aa,"HorizontalGraphCompactor/lambda$1$Type",1589),D(1730,1,{},Glt);var J8t,Z8t;I(aa,"LGraphToCGraphTransformer",1730),D(1738,1,ti,wS),h.Mb=function(t){return t!=null},I(aa,"LGraphToCGraphTransformer/0methodref$nonNull$Type",1738),D(1731,1,{},iee),h.Kb=function(t){return u0(),xc(Q(l(l(t,60).g,10),(ft(),zi)))},I(aa,"LGraphToCGraphTransformer/lambda$0$Type",1731),D(1732,1,{},see),h.Kb=function(t){return u0(),r1t(l(l(t,60).g,154))},I(aa,"LGraphToCGraphTransformer/lambda$1$Type",1732),D(1741,1,ti,Oj),h.Mb=function(t){return u0(),De(l(t,60).g,10)},I(aa,"LGraphToCGraphTransformer/lambda$10$Type",1741),D(1742,1,fr,aee),h.Cd=function(t){Mpn(l(t,60))},I(aa,"LGraphToCGraphTransformer/lambda$11$Type",1742),D(1743,1,ti,oee),h.Mb=function(t){return u0(),De(l(t,60).g,154)},I(aa,"LGraphToCGraphTransformer/lambda$12$Type",1743),D(1747,1,fr,cee),h.Cd=function(t){o4n(l(t,60))},I(aa,"LGraphToCGraphTransformer/lambda$13$Type",1747),D(1744,1,fr,pYe),h.Cd=function(t){Nln(this.a,l(t,8))},h.a=0,I(aa,"LGraphToCGraphTransformer/lambda$14$Type",1744),D(1745,1,fr,bYe),h.Cd=function(t){Bln(this.a,l(t,116))},h.a=0,I(aa,"LGraphToCGraphTransformer/lambda$15$Type",1745),D(1746,1,fr,mYe),h.Cd=function(t){Pln(this.a,l(t,8))},h.a=0,I(aa,"LGraphToCGraphTransformer/lambda$16$Type",1746),D(1748,1,{},uee),h.Kb=function(t){return u0(),new bn(null,new vw(new hr(dr(qs(l(t,10)).a.Kc(),new j))))},I(aa,"LGraphToCGraphTransformer/lambda$17$Type",1748),D(1749,1,ti,lee),h.Mb=function(t){return u0(),Do(l(t,18))},I(aa,"LGraphToCGraphTransformer/lambda$18$Type",1749),D(1750,1,fr,vYe),h.Cd=function(t){Qvn(this.a,l(t,18))},I(aa,"LGraphToCGraphTransformer/lambda$19$Type",1750),D(1734,1,fr,wYe),h.Cd=function(t){Tbn(this.a,l(t,154))},I(aa,"LGraphToCGraphTransformer/lambda$2$Type",1734),D(1751,1,{},hee),h.Kb=function(t){return u0(),new bn(null,new kn(l(t,30).a,16))},I(aa,"LGraphToCGraphTransformer/lambda$20$Type",1751),D(1752,1,{},Nj),h.Kb=function(t){return u0(),new bn(null,new vw(new hr(dr(qs(l(t,10)).a.Kc(),new j))))},I(aa,"LGraphToCGraphTransformer/lambda$21$Type",1752),D(1753,1,{},fee),h.Kb=function(t){return u0(),l(Q(l(t,18),(ft(),fv)),15)},I(aa,"LGraphToCGraphTransformer/lambda$22$Type",1753),D(1754,1,ti,Pj),h.Mb=function(t){return qhn(l(t,15))},I(aa,"LGraphToCGraphTransformer/lambda$23$Type",1754),D(1755,1,fr,yYe),h.Cd=function(t){vkn(this.a,l(t,15))},I(aa,"LGraphToCGraphTransformer/lambda$24$Type",1755),D(1733,1,fr,Ret),h.Cd=function(t){xmn(this.a,this.b,l(t,154))},I(aa,"LGraphToCGraphTransformer/lambda$3$Type",1733),D(1735,1,{},dee),h.Kb=function(t){return u0(),new bn(null,new kn(l(t,30).a,16))},I(aa,"LGraphToCGraphTransformer/lambda$4$Type",1735),D(1736,1,{},gee),h.Kb=function(t){return u0(),new bn(null,new vw(new hr(dr(qs(l(t,10)).a.Kc(),new j))))},I(aa,"LGraphToCGraphTransformer/lambda$5$Type",1736),D(1737,1,{},pee),h.Kb=function(t){return u0(),l(Q(l(t,18),(ft(),fv)),15)},I(aa,"LGraphToCGraphTransformer/lambda$6$Type",1737),D(1739,1,fr,xYe),h.Cd=function(t){Dkn(this.a,l(t,15))},I(aa,"LGraphToCGraphTransformer/lambda$8$Type",1739),D(1740,1,fr,jet),h.Cd=function(t){ahn(this.a,this.b,l(t,154))},I(aa,"LGraphToCGraphTransformer/lambda$9$Type",1740),D(1729,1,{},yS),h.cf=function(t){var n,r,a,o,f;for(this.a=t,this.d=new jie,this.c=We(z_e,Rn,125,this.a.a.a.c.length,0,1),this.b=0,r=new G(this.a.a.a);r.a=te&&(vt(f,pt(L)),Me=b.Math.max(Me,$e[L-1]-B),w+=J,fe+=$e[L-1]-fe,B=$e[L-1],J=E[L]),J=b.Math.max(J,E[L]),++L;w+=J}V=b.Math.min(1/Me,1/n.b/w),V>a&&(a=V,r=f)}return r},h.pg=function(){return!1},I(Od,"MSDCutIndexHeuristic",816),D(1683,1,ts,Fee),h.Kf=function(t,n){$An(l(t,36),n)},I(Od,"SingleEdgeGraphWrapper",1683),D(232,22,{3:1,34:1,22:1,232:1},E_);var O6,IT,OT,h4,qL,N6,NT=Fr(ou,"CenterEdgeLabelPlacementStrategy",232,Hr,Cvn,_0n),hxt;D(431,22,{3:1,34:1,22:1,431:1},N3e);var lLe,S1e,hLe=Fr(ou,"ConstraintCalculationStrategy",431,Hr,Upn,A0n),fxt;D(322,22,{3:1,34:1,22:1,322:1,188:1,196:1},wse),h.dg=function(){return $pt(this)},h.qg=function(){return $pt(this)};var mB,HL,fLe,dLe=Fr(ou,"CrossingMinimizationStrategy",322,Hr,j2n,L0n),dxt;D(351,22,{3:1,34:1,22:1,351:1},yse);var gLe,_1e,YK,pLe=Fr(ou,"CuttingStrategy",351,Hr,$2n,M0n),gxt;D(348,22,{3:1,34:1,22:1,348:1,188:1,196:1},uO),h.dg=function(){return M2t(this)},h.qg=function(){return M2t(this)};var bLe,A1e,PT,L1e,BT,mLe=Fr(ou,"CycleBreakingStrategy",348,Hr,Hmn,D0n),pxt;D(428,22,{3:1,34:1,22:1,428:1},P3e);var XK,vLe,wLe=Fr(ou,"DirectionCongruency",428,Hr,Vpn,I0n),bxt;D(460,22,{3:1,34:1,22:1,460:1},xse);var FT,M1e,P6,mxt=Fr(ou,"EdgeConstraint",460,Hr,z2n,j0n),vxt;D(283,22,{3:1,34:1,22:1,283:1},T_);var D1e,I1e,O1e,N1e,QK,P1e,yLe=Fr(ou,"EdgeLabelSideSelection",283,Hr,kvn,$0n),wxt;D(488,22,{3:1,34:1,22:1,488:1},B3e);var JK,xLe,kLe=Fr(ou,"EdgeStraighteningStrategy",488,Hr,Jpn,z0n),yxt;D(281,22,{3:1,34:1,22:1,281:1},C_);var B1e,ELe,TLe,ZK,CLe,SLe,_Le=Fr(ou,"FixedAlignment",281,Hr,Evn,R0n),xxt;D(282,22,{3:1,34:1,22:1,282:1},S_);var ALe,LLe,MLe,DLe,VL,ILe,OLe=Fr(ou,"GraphCompactionStrategy",282,Hr,Tvn,O0n),kxt;D(259,22,{3:1,34:1,22:1,259:1},uy);var RT,eW,jT,vf,UL,tW,$T,B6,nW,GL,F1e=Fr(ou,"GraphProperties",259,Hr,c3n,N0n),Ext;D(299,22,{3:1,34:1,22:1,299:1},kse);var vB,R1e,j1e,$1e=Fr(ou,"GreedySwitchType",299,Hr,q2n,P0n),Txt;D(311,22,{3:1,34:1,22:1,311:1},Ese);var Ux,wB,F6,Cxt=Fr(ou,"InLayerConstraint",311,Hr,H2n,B0n),Sxt;D(429,22,{3:1,34:1,22:1,429:1},F3e);var z1e,NLe,PLe=Fr(ou,"InteractiveReferencePoint",429,Hr,Hpn,F0n),_xt,BLe,Gx,c3,rW,FLe,RLe,iW,jLe,yB,sW,KL,Kx,pp,q1e,aW,Wc,$Le,jb,Lu,H1e,V1e,xB,hv,u3,Wx,zLe,Yx,kB,f4,o1,$f,U1e,R6,Ki,zi,qLe,HLe,VLe,ULe,GLe,G1e,oW,jl,l3,K1e,Xx,WL,W1,j6,h3,$6,z6,zT,fv,KLe,W1e,Y1e,Qx;D(171,22,{3:1,34:1,22:1,171:1},lO);var YL,$b,XL,d4,EB,WLe=Fr(ou,"LayerConstraint",171,Hr,Umn,q0n),Axt;D(859,1,Pf,Yre),h.hf=function(t){sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,VEe),""),"Direction Congruency"),"Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other."),iMe),(g2(),ps)),wLe),un((r1(),Pn))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,UEe),""),"Feedback Edges"),"Whether feedback edges should be highlighted by routing around the nodes."),(Hn(),!1)),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,fG),""),"Interactive Reference Point"),"Determines which point of a node is considered by interactive layout phases."),lMe),ps),PLe),un(Pn)))),Qs(t,fG,zhe,k9t),Qs(t,fG,pL,x9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,GEe),""),"Merge Edges"),"Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,KEe),""),"Merge Hierarchy-Crossing Edges"),"If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port."),!0),ya),Ns),un(Pn)))),sn(t,new Xt(Nun(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,WEe),""),"Allow Non-Flow Ports To Switch Sides"),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),!1),ya),Ns),un(yv)),he(le(zt,1),dt,2,6,["org.eclipse.elk.layered.northOrSouthPort"])))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,YEe),""),"Port Sorting Strategy"),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),vMe),ps),_De),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,XEe),""),"Thoroughness"),"How much effort should be spent to produce a nice layout."),pt(7)),Tc),ro),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,QEe),""),"Add Unnecessary Bendpoints"),"Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,JEe),""),"Generate Position and Layer IDs"),"If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,zhe),"cycleBreaking"),"Cycle Breaking Strategy"),"Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right)."),rMe),ps),mLe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,qP),hfe),"Node Layering Strategy"),"Strategy for node layering."),dMe),ps),pDe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ZEe),hfe),"Layer Constraint"),"Determines a constraint on the placement of the node regarding the layering."),hMe),ps),WLe),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,eTe),hfe),"Layer Choice Constraint"),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),Tc),ro),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,tTe),hfe),"Layer ID"),"Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),pt(-1)),Tc),ro),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,qhe),J3t),"Upper Bound On Width [MinWidth Layerer]"),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),pt(4)),Tc),ro),un(Pn)))),Qs(t,qhe,qP,L9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Hhe),J3t),"Upper Layer Estimation Scaling Factor [MinWidth Layerer]"),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),pt(2)),Tc),ro),un(Pn)))),Qs(t,Hhe,qP,D9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Vhe),Z3t),"Node Promotion Strategy"),"Reduces number of dummy nodes after layering phase (if possible)."),fMe),ps),TDe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Uhe),Z3t),"Max Node Promotion Iterations"),"Limits the number of iterations for node promotion."),pt(0)),Tc),ro),un(Pn)))),Qs(t,Uhe,Vhe,null),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Ghe),"layering.coffmanGraham"),"Layer Bound"),"The maximum number of nodes allowed per layer."),pt(Ii)),Tc),ro),un(Pn)))),Qs(t,Ghe,qP,T9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,pL),gT),"Crossing Minimization Strategy"),"Strategy for crossing minimization."),nMe),ps),dLe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,nTe),gT),"Force Node Model Order"),"The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Khe),gT),"Hierarchical Sweepiness"),"How likely it is to use cross-hierarchy (1) vs bottom-up (-1)."),.1),fo),ta),un(Pn)))),Qs(t,Khe,CG,Wxt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Whe),gT),"Semi-Interactive Crossing Minimization"),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),!1),ya),Ns),un(Pn)))),Qs(t,Whe,pL,e9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,rTe),gT),"In Layer Predecessor of"),"Allows to set a constraint which specifies of which node the current node is the predecessor. If set to 's' then the node is the predecessor of 's' and is in the same layer"),null),J6),zt),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,iTe),gT),"In Layer Successor of"),"Allows to set a constraint which specifies of which node the current node is the successor. If set to 's' then the node is the successor of 's' and is in the same layer"),null),J6),zt),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,sTe),gT),"Position Choice Constraint"),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),Tc),ro),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,aTe),gT),"Position ID"),"Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),pt(-1)),Tc),ro),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,oTe),eyt),"Greedy Switch Activation Threshold"),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),pt(40)),Tc),ro),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Yhe),eyt),"Greedy Switch Crossing Minimization"),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),tMe),ps),$1e),un(Pn)))),Qs(t,Yhe,pL,Gxt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,dG),"crossingMinimization.greedySwitchHierarchical"),"Greedy Switch Crossing Minimization (hierarchical)"),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),eMe),ps),$1e),un(Pn)))),Qs(t,dG,pL,Hxt),Qs(t,dG,CG,Vxt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,k6),tyt),"Node Placement Strategy"),"Strategy for node placement."),mMe),ps),wDe),un(Pn)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,gG),tyt),"Favor Straight Edges Over Balancing"),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),ya),Ns),un(Pn)))),Qs(t,gG,k6,q9t),Qs(t,gG,k6,H9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Xhe),nyt),"BK Edge Straightening"),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),gMe),ps),kLe),un(Pn)))),Qs(t,Xhe,k6,R9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Qhe),nyt),"BK Fixed Alignment"),"Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four."),pMe),ps),_Le),un(Pn)))),Qs(t,Qhe,k6,$9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Jhe),"nodePlacement.linearSegments"),"Linear Segments Deflection Dampening"),"Dampens the movement of nodes to keep the diagram from getting too large."),.3),fo),ta),un(Pn)))),Qs(t,Jhe,k6,U9t),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,Zhe),"nodePlacement.networkSimplex"),"Node Flexibility"),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),ps),mde),un(ha)))),Qs(t,Zhe,k6,Y9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,efe),"nodePlacement.networkSimplex.nodeFlexibility"),"Node Flexibility Default"),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),bMe),ps),mde),un(Pn)))),Qs(t,efe,k6,W9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,cTe),ryt),"Self-Loop Distribution"),"Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE."),oMe),ps),MDe),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,uTe),ryt),"Self-Loop Ordering"),"Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE."),cMe),ps),DDe),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,pG),"edgeRouting.splines"),"Spline Routing Mode"),"Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes."),uMe),ps),ODe),un(Pn)))),Qs(t,pG,HP,h9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,bG),"edgeRouting.splines.sloppy"),"Sloppy Spline Layer Spacing Factor"),"Spacing factor for routing area between layers when using sloppy spline routing."),.2),fo),ta),un(Pn)))),Qs(t,bG,HP,d9t),Qs(t,bG,pG,g9t),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,tfe),"edgeRouting.polyline"),"Sloped Edge Zone Width"),"Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer."),2),fo),ta),un(Pn)))),Qs(t,tfe,HP,o9t),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,lTe),U1),"Spacing Base Value"),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,hTe),U1),"Edge Node Between Layers Spacing"),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,fTe),U1),"Edge Edge Between Layer Spacing"),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,dTe),U1),"Node Node Between Layers Spacing"),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,gTe),TTe),"Direction Priority"),"Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase."),pt(0)),Tc),ro),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,pTe),TTe),"Shortness Priority"),"Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase."),pt(0)),Tc),ro),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,bTe),TTe),"Straightness Priority"),"Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement."),pt(0)),Tc),ro),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,nfe),CTe),w3t),"Tries to further compact components (disconnected sub-graphs)."),!1),ya),Ns),un(Pn)))),Qs(t,nfe,lL,!0),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,mTe),iyt),"Post Compaction Strategy"),syt),XLe),ps),OLe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,vTe),iyt),"Post Compaction Constraint Calculation"),syt),YLe),ps),hLe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,mG),STe),"High Degree Node Treatment"),"Makes room around high degree nodes to place leafs and trees."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,rfe),STe),"High Degree Node Threshold"),"Whether a node is considered to have a high degree."),pt(16)),Tc),ro),un(Pn)))),Qs(t,rfe,mG,!0),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ife),STe),"High Degree Node Maximum Tree Height"),"Maximum height of a subtree connected to a high degree node to be moved to separate layers."),pt(5)),Tc),ro),un(Pn)))),Qs(t,ife,mG,!0),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,fp),_Te),"Graph Wrapping Strategy"),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),xMe),ps),FDe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,vG),_Te),"Additional Wrapped Edges Spacing"),"To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing."),10),fo),ta),un(Pn)))),Qs(t,vG,fp,ckt),Qs(t,vG,fp,ukt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,wG),_Te),"Correction Factor for Wrapping"),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),fo),ta),un(Pn)))),Qs(t,wG,fp,hkt),Qs(t,wG,fp,fkt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,bL),ayt),"Cutting Strategy"),"The strategy by which the layer indexes are determined at which the layering crumbles into chunks."),yMe),ps),pLe),un(Pn)))),Qs(t,bL,fp,vkt),Qs(t,bL,fp,wkt),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,sfe),ayt),"Manually Specified Cuts"),"Allows the user to specify her own cuts for a certain graph."),X1),mf),un(Pn)))),Qs(t,sfe,bL,gkt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,afe),"wrapping.cutting.msd"),"MSD Freedom"),"The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts."),wMe),Tc),ro),un(Pn)))),Qs(t,afe,bL,bkt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,yG),oyt),"Validification Strategy"),"When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed."),kMe),ps),BDe),un(Pn)))),Qs(t,yG,fp,Dkt),Qs(t,yG,fp,Ikt),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,xG),oyt),"Valid Indices for Wrapping"),null),X1),mf),un(Pn)))),Qs(t,xG,fp,Akt),Qs(t,xG,fp,Lkt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,kG),ATe),"Improve Cuts"),"For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought."),!0),ya),Ns),un(Pn)))),Qs(t,kG,fp,Ekt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,EG),ATe),"Distance Penalty When Improving Cuts"),null),2),fo),ta),un(Pn)))),Qs(t,EG,fp,xkt),Qs(t,EG,kG,!0),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ofe),ATe),"Improve Wrapped Edges"),"The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges."),!0),ya),Ns),un(Pn)))),Qs(t,ofe,fp,Ckt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,wTe),ffe),"Edge Label Side Selection"),"Method to decide on edge label sides."),aMe),ps),yLe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,yTe),ffe),"Edge Center Label Placement Strategy"),"Determines in which layer center labels of long edges should be placed."),sMe),ps),NT),rs(Pn,he(le(xg,1),it,170,0,[S2]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,TG),mL),"Consider Model Order"),"Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting."),ZLe),ps),SDe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,xTe),mL),"Consider Port Order"),"If disabled the port order of output ports is derived from the edge order and input ports are ordered by their incoming connections. If enabled all ports are ordered by the port model order."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,kTe),mL),"No Model Order"),"Set on a node to not set a model order for this node even though it is a real node."),!1),ya),Ns),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,cfe),mL),"Consider Model Order for Components"),"If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected."),QLe),ps),mAe),un(Pn)))),Qs(t,cfe,lL,null),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ETe),mL),"Long Edge Ordering Strategy"),"Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout."),JLe),ps),mDe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ufe),mL),"Crossing Counter Node Order Influence"),"Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0)."),0),fo),ta),un(Pn)))),Qs(t,ufe,TG,null),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,lfe),mL),"Crossing Counter Port Order Influence"),"Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0)."),0),fo),ta),un(Pn)))),Qs(t,lfe,TG,null),Twt((new Xre,t))};var Lxt,Mxt,Dxt,YLe,Ixt,XLe,Oxt,QLe,Nxt,Pxt,Bxt,JLe,Fxt,Rxt,jxt,ZLe,$xt,zxt,qxt,eMe,Hxt,Vxt,Uxt,tMe,Gxt,Kxt,Wxt,Yxt,Xxt,Qxt,Jxt,Zxt,e9t,t9t,nMe,n9t,rMe,r9t,iMe,i9t,sMe,s9t,aMe,a9t,o9t,c9t,oMe,u9t,cMe,l9t,uMe,h9t,f9t,d9t,g9t,p9t,b9t,m9t,v9t,w9t,y9t,lMe,x9t,k9t,E9t,T9t,C9t,S9t,hMe,_9t,A9t,L9t,M9t,D9t,I9t,O9t,fMe,N9t,dMe,P9t,B9t,F9t,gMe,R9t,j9t,pMe,$9t,z9t,q9t,H9t,V9t,U9t,G9t,K9t,bMe,W9t,Y9t,X9t,mMe,Q9t,vMe,J9t,Z9t,ekt,tkt,nkt,rkt,ikt,skt,akt,okt,ckt,ukt,lkt,hkt,fkt,dkt,gkt,pkt,wMe,bkt,mkt,yMe,vkt,wkt,ykt,xkt,kkt,Ekt,Tkt,Ckt,Skt,xMe,_kt,Akt,Lkt,Mkt,kMe,Dkt,Ikt;I(ou,"LayeredMetaDataProvider",859),D(998,1,Pf,Xre),h.hf=function(t){Twt(t)};var Rd,X1e,cW,QL,uW,EMe,lW,g4,hW,TMe,CMe,fW,Q1e,yg,J1e,f3,SMe,TB,Z1e,_Me,Okt,Nkt,Pkt,dW,ede,JL,dv,Bkt,Rh,AMe,LMe,gW,tde,jd,pW,bp,MMe,DMe,IMe,nde,rde,OMe,x2,ide,NMe,p4,PMe,BMe,FMe,bW,b4,gv,RMe,jMe,cc,$Me,Fkt,Qu,mW,zMe,qMe,HMe,zb,pv,vW,VMe,UMe,wW,d3,GMe,sde,ZL,KMe,g3,eM,yW,bv,ade,qT,xW,mv,WMe,YMe,XMe,HT,QMe,Rkt,jkt,$kt,zkt,p3,m4,Ms,k2,qkt,v4,JMe,VT,ZMe,w4,Hkt,UT,eDe,Jx,Vkt,Ukt,CB,ode,tDe,SB,x0,q6,H6,b3,vv,kW,y4,cde,GT,KT,m3,V6,ude,_B,tM,nM,Gkt,Kkt,Wkt,nDe,Ykt,lde,rDe,iDe,sDe,aDe,hde,oDe,cDe,uDe,lDe,fde,EW;I(ou,"LayeredOptions",998),D(999,1,{},Ree),h.sf=function(){var t;return t=new qQe,t},h.tf=function(t){},I(ou,"LayeredOptions/LayeredFactory",999),D(1391,1,{}),h.a=0;var Xkt;I(Uc,"ElkSpacings/AbstractSpacingsBuilder",1391),D(792,1391,{},D8e);var TW,Qkt;I(ou,"LayeredSpacings/LayeredSpacingsBuilder",792),D(265,22,{3:1,34:1,22:1,265:1,188:1,196:1},M5),h.dg=function(){return jbt(this)},h.qg=function(){return jbt(this)};var WT,dde,YT,hDe,fDe,dDe,CW,gde,gDe,pDe=Fr(ou,"LayeringStrategy",265,Hr,Rwn,H0n),Jkt;D(390,22,{3:1,34:1,22:1,390:1},Tse);var pde,bDe,SW,mDe=Fr(ou,"LongEdgeOrderingStrategy",390,Hr,V2n,V0n),Zkt;D(203,22,{3:1,34:1,22:1,203:1},bq);var U6,G6,_W,bde,mde=Fr(ou,"NodeFlexibility",203,Hr,Zbn,U0n),eEt;D(323,22,{3:1,34:1,22:1,323:1,188:1,196:1},hO),h.dg=function(){return L2t(this)},h.qg=function(){return L2t(this)};var rM,vde,wde,iM,vDe,wDe=Fr(ou,"NodePlacementStrategy",323,Hr,Vmn,G0n),tEt;D(243,22,{3:1,34:1,22:1,243:1},ly);var yDe,v3,x4,AB,xDe,kDe,LB,EDe,AW,LW,TDe=Fr(ou,"NodePromotionStrategy",243,Hr,u3n,K0n),nEt;D(284,22,{3:1,34:1,22:1,284:1},mq);var CDe,E2,yde,xde,SDe=Fr(ou,"OrderingStrategy",284,Hr,emn,W0n),rEt;D(430,22,{3:1,34:1,22:1,430:1},R3e);var kde,Ede,_De=Fr(ou,"PortSortingStrategy",430,Hr,Gpn,Y0n),iEt;D(463,22,{3:1,34:1,22:1,463:1},Cse);var $l,zu,sM,sEt=Fr(ou,"PortType",463,Hr,U2n,X0n),aEt;D(387,22,{3:1,34:1,22:1,387:1},Sse);var ADe,Tde,LDe,MDe=Fr(ou,"SelfLoopDistributionStrategy",387,Hr,G2n,Q0n),oEt;D(349,22,{3:1,34:1,22:1,349:1},_se);var Cde,MB,Sde,DDe=Fr(ou,"SelfLoopOrderingStrategy",349,Hr,K2n,J0n),cEt;D(312,1,{312:1},xvt),I(ou,"Spacings",312),D(350,22,{3:1,34:1,22:1,350:1},Ase);var _de,IDe,aM,ODe=Fr(ou,"SplineRoutingMode",350,Hr,W2n,Z0n),uEt;D(352,22,{3:1,34:1,22:1,352:1},Lse);var Ade,NDe,PDe,BDe=Fr(ou,"ValidifyStrategy",352,Hr,Y2n,e1n),lEt;D(388,22,{3:1,34:1,22:1,388:1},Mse);var k4,Lde,XT,FDe=Fr(ou,"WrappingStrategy",388,Hr,X2n,t1n),hEt;D(1398,1,Uo,Ure),h.rg=function(t){return l(t,36),fEt},h.Kf=function(t,n){NLn(this,l(t,36),n)};var fEt;I(LG,"DepthFirstCycleBreaker",1398),D(793,1,Uo,Q4e),h.rg=function(t){return l(t,36),dEt},h.Kf=function(t,n){FIn(this,l(t,36),n)},h.sg=function(t){return l(jt(t,aU(this.d,t.c.length)),10)};var dEt;I(LG,"GreedyCycleBreaker",793),D(1401,793,Uo,$tt),h.sg=function(t){var n,r,a,o;for(o=null,n=Ii,a=new G(t);a.a1&&(Rt(Bt(Q(eo((Sn(0,t.c.length),l(t.c[0],10))),(Nt(),f3))))?q2t(t,this.d,l(this,669)):(Cn(),Vs(t,this.d)),Hft(this.e,t))},h.lg=function(t,n,r,a){var o,f,g,w,E,C,L;for(n!=ast(r,t.length)&&(f=t[n-(r?1:-1)],S6e(this.f,f,r?(qo(),zu):(qo(),$l))),o=t[n][0],L=!a||o.k==(Zn(),Us),C=O1(t[n]),this.vg(C,L,!1,r),g=0,E=new G(C);E.a"),t0?loe(this.a,t[n-1],t[n]):!r&&n1&&(Rt(Bt(Q(eo((Sn(0,t.c.length),l(t.c[0],10))),(Nt(),f3))))?q2t(t,this.d,this):(Cn(),Vs(t,this.d)),Rt(Bt(Q(eo((Sn(0,t.c.length),l(t.c[0],10))),f3)))||Hft(this.e,t))},I(Cl,"ModelOrderBarycenterHeuristic",669),D(1866,1,ii,zYe),h.Ne=function(t,n){return O9n(this.a,l(t,10),l(n,10))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Cl,"ModelOrderBarycenterHeuristic/lambda$0$Type",1866),D(1423,1,Uo,Jre),h.rg=function(t){var n;return l(t,36),n=Oq(LEt),fi(n,(uo(),bu),(vo(),RK)),n},h.Kf=function(t,n){bpn((l(t,36),n))};var LEt;I(Cl,"NoCrossingMinimizer",1423),D(809,413,uCe,o3e),h.tg=function(t,n,r){var a,o,f,g,w,E,C,L,B,z,V;switch(B=this.g,r.g){case 1:{for(o=0,f=0,L=new G(t.j);L.a1&&(o.j==(Ct(),ar)?this.b[t]=!0:o.j==er&&t>0&&(this.b[t-1]=!0))},h.f=0,I(bg,"AllCrossingsCounter",1861),D(595,1,{},TV),h.b=0,h.d=0,I(bg,"BinaryIndexedTree",595),D(532,1,{},IO);var $De,DW;I(bg,"CrossingsCounter",532),D(1950,1,ii,qYe),h.Ne=function(t,n){return qdn(this.a,l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(bg,"CrossingsCounter/lambda$0$Type",1950),D(1951,1,ii,HYe),h.Ne=function(t,n){return Hdn(this.a,l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(bg,"CrossingsCounter/lambda$1$Type",1951),D(1952,1,ii,VYe),h.Ne=function(t,n){return Vdn(this.a,l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(bg,"CrossingsCounter/lambda$2$Type",1952),D(1953,1,ii,UYe),h.Ne=function(t,n){return Udn(this.a,l(t,12),l(n,12))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(bg,"CrossingsCounter/lambda$3$Type",1953),D(1954,1,fr,GYe),h.Cd=function(t){Uvn(this.a,l(t,12))},I(bg,"CrossingsCounter/lambda$4$Type",1954),D(1955,1,ti,KYe),h.Mb=function(t){return bln(this.a,l(t,12))},I(bg,"CrossingsCounter/lambda$5$Type",1955),D(1956,1,fr,WYe),h.Cd=function(t){Dtt(this,t)},I(bg,"CrossingsCounter/lambda$6$Type",1956),D(1957,1,fr,qet),h.Cd=function(t){var n;jk(),gb(this.b,(n=this.a,l(t,12),n))},I(bg,"CrossingsCounter/lambda$7$Type",1957),D(839,1,Ld,Xj),h.Lb=function(t){return jk(),ns(l(t,12),(ft(),jl))},h.Fb=function(t){return this===t},h.Mb=function(t){return jk(),ns(l(t,12),(ft(),jl))},I(bg,"CrossingsCounter/lambda$8$Type",839),D(1949,1,{},YYe),I(bg,"HyperedgeCrossingsCounter",1949),D(478,1,{34:1,478:1},Urt),h.Fd=function(t){return V5n(this,l(t,478))},h.b=0,h.c=0,h.e=0,h.f=0;var TOn=I(bg,"HyperedgeCrossingsCounter/Hyperedge",478);D(374,1,{34:1,374:1},CH),h.Fd=function(t){return iTn(this,l(t,374))},h.b=0,h.c=0;var MEt=I(bg,"HyperedgeCrossingsCounter/HyperedgeCorner",374);D(531,22,{3:1,34:1,22:1,531:1},j3e);var cM,uM,DEt=Fr(bg,"HyperedgeCrossingsCounter/HyperedgeCorner/Type",531,Hr,Kpn,r1n),IEt;D(1425,1,Uo,Zre),h.rg=function(t){return l(Q(l(t,36),(ft(),Lu)),21).Hc((Ho(),vf))?OEt:null},h.Kf=function(t,n){p8n(this,l(t,36),n)};var OEt;I(Go,"InteractiveNodePlacer",1425),D(1426,1,Uo,eie),h.rg=function(t){return l(Q(l(t,36),(ft(),Lu)),21).Hc((Ho(),vf))?NEt:null},h.Kf=function(t,n){Z6n(this,l(t,36),n)};var NEt,IW,OW;I(Go,"LinearSegmentsNodePlacer",1426),D(261,1,{34:1,261:1},Pwe),h.Fd=function(t){return Aun(this,l(t,261))},h.Fb=function(t){var n;return De(t,261)?(n=l(t,261),this.b==n.b):!1},h.Hb=function(){return this.b},h.Ib=function(){return"ls"+Tb(this.e)},h.a=0,h.b=0,h.c=-1,h.d=-1,h.g=0;var PEt=I(Go,"LinearSegmentsNodePlacer/LinearSegment",261);D(1428,1,Uo,bst),h.rg=function(t){return l(Q(l(t,36),(ft(),Lu)),21).Hc((Ho(),vf))?BEt:null},h.Kf=function(t,n){AIn(this,l(t,36),n)},h.b=0,h.g=0;var BEt;I(Go,"NetworkSimplexPlacer",1428),D(1447,1,ii,Gee),h.Ne=function(t,n){return ru(l(t,17).a,l(n,17).a)},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Go,"NetworkSimplexPlacer/0methodref$compare$Type",1447),D(1449,1,ii,Kee),h.Ne=function(t,n){return ru(l(t,17).a,l(n,17).a)},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Go,"NetworkSimplexPlacer/1methodref$compare$Type",1449),D(655,1,{655:1},Het);var COn=I(Go,"NetworkSimplexPlacer/EdgeRep",655);D(412,1,{412:1},D5e),h.b=!1;var SOn=I(Go,"NetworkSimplexPlacer/NodeRep",412);D(515,13,{3:1,4:1,20:1,31:1,56:1,13:1,16:1,15:1,59:1,515:1},QQe),I(Go,"NetworkSimplexPlacer/Path",515),D(1429,1,{},Wee),h.Kb=function(t){return l(t,18).d.i.k},I(Go,"NetworkSimplexPlacer/Path/lambda$0$Type",1429),D(1430,1,ti,Yee),h.Mb=function(t){return l(t,273)==(Zn(),Aa)},I(Go,"NetworkSimplexPlacer/Path/lambda$1$Type",1430),D(1431,1,{},Xee),h.Kb=function(t){return l(t,18).d.i},I(Go,"NetworkSimplexPlacer/Path/lambda$2$Type",1431),D(1432,1,ti,XYe),h.Mb=function(t){return Lrt(I1t(l(t,10)))},I(Go,"NetworkSimplexPlacer/Path/lambda$3$Type",1432),D(1433,1,ti,Qee),h.Mb=function(t){return Sdn(l(t,12))},I(Go,"NetworkSimplexPlacer/lambda$0$Type",1433),D(1434,1,fr,Vet),h.Cd=function(t){ohn(this.a,this.b,l(t,12))},I(Go,"NetworkSimplexPlacer/lambda$1$Type",1434),D(1443,1,fr,QYe),h.Cd=function(t){Okn(this.a,l(t,18))},I(Go,"NetworkSimplexPlacer/lambda$10$Type",1443),D(1444,1,{},Jee),h.Kb=function(t){return Sh(),new bn(null,new kn(l(t,30).a,16))},I(Go,"NetworkSimplexPlacer/lambda$11$Type",1444),D(1445,1,fr,JYe),h.Cd=function(t){_Sn(this.a,l(t,10))},I(Go,"NetworkSimplexPlacer/lambda$12$Type",1445),D(1446,1,{},Zee),h.Kb=function(t){return Sh(),pt(l(t,125).e)},I(Go,"NetworkSimplexPlacer/lambda$13$Type",1446),D(1448,1,{},ete),h.Kb=function(t){return Sh(),pt(l(t,125).e)},I(Go,"NetworkSimplexPlacer/lambda$15$Type",1448),D(1450,1,ti,tte),h.Mb=function(t){return Sh(),l(t,412).c.k==(Zn(),Ps)},I(Go,"NetworkSimplexPlacer/lambda$17$Type",1450),D(1451,1,ti,nte),h.Mb=function(t){return Sh(),l(t,412).c.j.c.length>1},I(Go,"NetworkSimplexPlacer/lambda$18$Type",1451),D(1452,1,fr,Tat),h.Cd=function(t){f5n(this.c,this.b,this.d,this.a,l(t,412))},h.c=0,h.d=0,I(Go,"NetworkSimplexPlacer/lambda$19$Type",1452),D(1435,1,{},rte),h.Kb=function(t){return Sh(),new bn(null,new kn(l(t,30).a,16))},I(Go,"NetworkSimplexPlacer/lambda$2$Type",1435),D(1453,1,fr,ZYe),h.Cd=function(t){uhn(this.a,l(t,12))},h.a=0,I(Go,"NetworkSimplexPlacer/lambda$20$Type",1453),D(1454,1,{},ite),h.Kb=function(t){return Sh(),new bn(null,new kn(l(t,30).a,16))},I(Go,"NetworkSimplexPlacer/lambda$21$Type",1454),D(1455,1,fr,eXe),h.Cd=function(t){xhn(this.a,l(t,10))},I(Go,"NetworkSimplexPlacer/lambda$22$Type",1455),D(1456,1,ti,ste),h.Mb=function(t){return Lrt(t)},I(Go,"NetworkSimplexPlacer/lambda$23$Type",1456),D(1457,1,{},ate),h.Kb=function(t){return Sh(),new bn(null,new kn(l(t,30).a,16))},I(Go,"NetworkSimplexPlacer/lambda$24$Type",1457),D(1458,1,ti,tXe),h.Mb=function(t){return Mln(this.a,l(t,10))},I(Go,"NetworkSimplexPlacer/lambda$25$Type",1458),D(1459,1,fr,Uet),h.Cd=function(t){F9n(this.a,this.b,l(t,10))},I(Go,"NetworkSimplexPlacer/lambda$26$Type",1459),D(1460,1,ti,s8),h.Mb=function(t){return Sh(),!Do(l(t,18))},I(Go,"NetworkSimplexPlacer/lambda$27$Type",1460),D(1461,1,ti,Qj),h.Mb=function(t){return Sh(),!Do(l(t,18))},I(Go,"NetworkSimplexPlacer/lambda$28$Type",1461),D(1462,1,{},nXe),h.Ve=function(t,n){return chn(this.a,l(t,30),l(n,30))},I(Go,"NetworkSimplexPlacer/lambda$29$Type",1462),D(1436,1,{},ote),h.Kb=function(t){return Sh(),new bn(null,new vw(new hr(dr(qs(l(t,10)).a.Kc(),new j))))},I(Go,"NetworkSimplexPlacer/lambda$3$Type",1436),D(1437,1,ti,cte),h.Mb=function(t){return Sh(),Rbn(l(t,18))},I(Go,"NetworkSimplexPlacer/lambda$4$Type",1437),D(1438,1,fr,rXe),h.Cd=function(t){BAn(this.a,l(t,18))},I(Go,"NetworkSimplexPlacer/lambda$5$Type",1438),D(1439,1,{},ute),h.Kb=function(t){return Sh(),new bn(null,new kn(l(t,30).a,16))},I(Go,"NetworkSimplexPlacer/lambda$6$Type",1439),D(1440,1,ti,Jj),h.Mb=function(t){return Sh(),l(t,10).k==(Zn(),Ps)},I(Go,"NetworkSimplexPlacer/lambda$7$Type",1440),D(1441,1,{},lte),h.Kb=function(t){return Sh(),new bn(null,new vw(new hr(dr(sp(l(t,10)).a.Kc(),new j))))},I(Go,"NetworkSimplexPlacer/lambda$8$Type",1441),D(1442,1,ti,TS),h.Mb=function(t){return Sh(),Cdn(l(t,18))},I(Go,"NetworkSimplexPlacer/lambda$9$Type",1442),D(1424,1,Uo,tie),h.rg=function(t){return l(Q(l(t,36),(ft(),Lu)),21).Hc((Ho(),vf))?FEt:null},h.Kf=function(t,n){bLn(l(t,36),n)};var FEt;I(Go,"SimpleNodePlacer",1424),D(185,1,{185:1},f6),h.Ib=function(){var t;return t="",this.c==(xd(),w3)?t+=Dx:this.c==T2&&(t+=Mx),this.o==(D1(),wv)?t+=whe:this.o==Y1?t+="UP":t+="BALANCED",t},I(Ib,"BKAlignedLayout",185),D(523,22,{3:1,34:1,22:1,523:1},$3e);var T2,w3,REt=Fr(Ib,"BKAlignedLayout/HDirection",523,Hr,Ypn,i1n),jEt;D(522,22,{3:1,34:1,22:1,522:1},z3e);var wv,Y1,$Et=Fr(Ib,"BKAlignedLayout/VDirection",522,Hr,Xpn,s1n),zEt;D(1699,1,{},Get),I(Ib,"BKAligner",1699),D(1702,1,{},rgt),I(Ib,"BKCompactor",1702),D(663,1,{663:1},hte),h.a=0,I(Ib,"BKCompactor/ClassEdge",663),D(467,1,{467:1},WQe),h.a=null,h.b=0,I(Ib,"BKCompactor/ClassNode",467),D(1427,1,Uo,Xet),h.rg=function(t){return l(Q(l(t,36),(ft(),Lu)),21).Hc((Ho(),vf))?qEt:null},h.Kf=function(t,n){GIn(this,l(t,36),n)},h.d=!1;var qEt;I(Ib,"BKNodePlacer",1427),D(1700,1,{},fte),h.d=0,I(Ib,"NeighborhoodInformation",1700),D(1701,1,ii,iXe),h.Ne=function(t,n){return ywn(this,l(t,42),l(n,42))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Ib,"NeighborhoodInformation/NeighborComparator",1701),D(823,1,{}),I(Ib,"ThresholdStrategy",823),D(1825,823,{},YQe),h.wg=function(t,n,r){return this.a.o==(D1(),Y1)?gs:ia},h.xg=function(){},I(Ib,"ThresholdStrategy/NullThresholdStrategy",1825),D(587,1,{587:1},Qet),h.c=!1,h.d=!1,I(Ib,"ThresholdStrategy/Postprocessable",587),D(1826,823,{},XQe),h.wg=function(t,n,r){var a,o,f;return o=n==r,a=this.a.a[r.p]==n,o||a?(f=t,this.a.c==(xd(),w3)?(o&&(f=vle(this,n,!0)),!isNaN(f)&&!isFinite(f)&&a&&(f=vle(this,r,!1))):(o&&(f=vle(this,n,!0)),!isNaN(f)&&!isFinite(f)&&a&&(f=vle(this,r,!1))),f):t},h.xg=function(){for(var t,n,r,a,o;this.d.b!=0;)o=l(h2n(this.d),587),a=Lmt(this,o),a.a&&(t=a.a,r=Rt(this.a.f[this.a.g[o.b.p].p]),!(!r&&!Do(t)&&t.c.i.c==t.d.i.c)&&(n=N2t(this,o),n||Oln(this.e,o)));for(;this.e.a.c.length!=0;)N2t(this,l(P0t(this.e),587))},I(Ib,"ThresholdStrategy/SimpleThresholdStrategy",1826),D(645,1,{645:1,188:1,196:1},dte),h.dg=function(){return Vft(this)},h.qg=function(){return Vft(this)};var Mde;I(mfe,"EdgeRouterFactory",645),D(1485,1,Uo,nie),h.rg=function(t){return rSn(l(t,36))},h.Kf=function(t,n){ELn(l(t,36),n)};var HEt,VEt,UEt,GEt,KEt,zDe,WEt,YEt;I(mfe,"OrthogonalEdgeRouter",1485),D(1478,1,Uo,Yet),h.rg=function(t){return C8n(l(t,36))},h.Kf=function(t,n){GDn(this,l(t,36),n)};var XEt,QEt,JEt,ZEt,IB,eTt;I(mfe,"PolylineEdgeRouter",1478),D(1479,1,Ld,pte),h.Lb=function(t){return A7e(l(t,10))},h.Fb=function(t){return this===t},h.Mb=function(t){return A7e(l(t,10))},I(mfe,"PolylineEdgeRouter/1",1479),D(1872,1,ti,bte),h.Mb=function(t){return l(t,132).c==(J0(),qb)},I(i1,"HyperEdgeCycleDetector/lambda$0$Type",1872),D(1873,1,{},mte),h.Ze=function(t){return l(t,132).d},I(i1,"HyperEdgeCycleDetector/lambda$1$Type",1873),D(1874,1,ti,vte),h.Mb=function(t){return l(t,132).c==(J0(),qb)},I(i1,"HyperEdgeCycleDetector/lambda$2$Type",1874),D(1875,1,{},wte),h.Ze=function(t){return l(t,132).d},I(i1,"HyperEdgeCycleDetector/lambda$3$Type",1875),D(1876,1,{},yte),h.Ze=function(t){return l(t,132).d},I(i1,"HyperEdgeCycleDetector/lambda$4$Type",1876),D(1877,1,{},gte),h.Ze=function(t){return l(t,132).d},I(i1,"HyperEdgeCycleDetector/lambda$5$Type",1877),D(118,1,{34:1,118:1},xN),h.Fd=function(t){return Lun(this,l(t,118))},h.Fb=function(t){var n;return De(t,118)?(n=l(t,118),this.g==n.g):!1},h.Hb=function(){return this.g},h.Ib=function(){var t,n,r,a;for(t=new Th("{"),a=new G(this.n);a.a"+this.b+" ("+Whn(this.c)+")"},h.d=0,I(i1,"HyperEdgeSegmentDependency",132),D(528,22,{3:1,34:1,22:1,528:1},q3e);var qb,E4,tTt=Fr(i1,"HyperEdgeSegmentDependency/DependencyType",528,Hr,Qpn,a1n),nTt;D(1878,1,{},sXe),I(i1,"HyperEdgeSegmentSplitter",1878),D(1879,1,{},QJe),h.a=0,h.b=0,I(i1,"HyperEdgeSegmentSplitter/AreaRating",1879),D(339,1,{339:1},vae),h.a=0,h.b=0,h.c=0,I(i1,"HyperEdgeSegmentSplitter/FreeArea",339),D(1880,1,ii,a8),h.Ne=function(t,n){return Wfn(l(t,118),l(n,118))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(i1,"HyperEdgeSegmentSplitter/lambda$0$Type",1880),D(1881,1,fr,Cat),h.Cd=function(t){kmn(this.a,this.d,this.c,this.b,l(t,118))},h.b=0,I(i1,"HyperEdgeSegmentSplitter/lambda$1$Type",1881),D(1882,1,{},xte),h.Kb=function(t){return new bn(null,new kn(l(t,118).e,16))},I(i1,"HyperEdgeSegmentSplitter/lambda$2$Type",1882),D(1883,1,{},kte),h.Kb=function(t){return new bn(null,new kn(l(t,118).j,16))},I(i1,"HyperEdgeSegmentSplitter/lambda$3$Type",1883),D(1884,1,{},Ete),h.Ye=function(t){return ze(Ge(t))},I(i1,"HyperEdgeSegmentSplitter/lambda$4$Type",1884),D(664,1,{},Hae),h.a=0,h.b=0,h.c=0,I(i1,"OrthogonalRoutingGenerator",664),D(1703,1,{},Tte),h.Kb=function(t){return new bn(null,new kn(l(t,118).e,16))},I(i1,"OrthogonalRoutingGenerator/lambda$0$Type",1703),D(1704,1,{},Cte),h.Kb=function(t){return new bn(null,new kn(l(t,118).j,16))},I(i1,"OrthogonalRoutingGenerator/lambda$1$Type",1704),D(670,1,{}),I(vfe,"BaseRoutingDirectionStrategy",670),D(1870,670,{},eJe),h.yg=function(t,n,r){var a,o,f,g,w,E,C,L,B,z,V,J,te;if(!(t.r&&!t.q))for(L=n+t.o*r,C=new G(t.n);C.aDd&&(f=L,o=t,a=new lt(B,f),ui(g.a,a),Vw(this,g,o,a,!1),z=t.r,z&&(V=ze(Ge(ff(z.e,0))),a=new lt(V,f),ui(g.a,a),Vw(this,g,o,a,!1),f=n+z.o*r,o=z,a=new lt(V,f),ui(g.a,a),Vw(this,g,o,a,!1)),a=new lt(te,f),ui(g.a,a),Vw(this,g,o,a,!1)))},h.zg=function(t){return t.i.n.a+t.n.a+t.a.a},h.Ag=function(){return Ct(),Dr},h.Bg=function(){return Ct(),Qn},I(vfe,"NorthToSouthRoutingStrategy",1870),D(1871,670,{},tJe),h.yg=function(t,n,r){var a,o,f,g,w,E,C,L,B,z,V,J,te;if(!(t.r&&!t.q))for(L=n-t.o*r,C=new G(t.n);C.aDd&&(f=L,o=t,a=new lt(B,f),ui(g.a,a),Vw(this,g,o,a,!1),z=t.r,z&&(V=ze(Ge(ff(z.e,0))),a=new lt(V,f),ui(g.a,a),Vw(this,g,o,a,!1),f=n-z.o*r,o=z,a=new lt(V,f),ui(g.a,a),Vw(this,g,o,a,!1)),a=new lt(te,f),ui(g.a,a),Vw(this,g,o,a,!1)))},h.zg=function(t){return t.i.n.a+t.n.a+t.a.a},h.Ag=function(){return Ct(),Qn},h.Bg=function(){return Ct(),Dr},I(vfe,"SouthToNorthRoutingStrategy",1871),D(1869,670,{},nJe),h.yg=function(t,n,r){var a,o,f,g,w,E,C,L,B,z,V,J,te;if(!(t.r&&!t.q))for(L=n+t.o*r,C=new G(t.n);C.aDd&&(f=L,o=t,a=new lt(f,B),ui(g.a,a),Vw(this,g,o,a,!0),z=t.r,z&&(V=ze(Ge(ff(z.e,0))),a=new lt(f,V),ui(g.a,a),Vw(this,g,o,a,!0),f=n+z.o*r,o=z,a=new lt(f,V),ui(g.a,a),Vw(this,g,o,a,!0)),a=new lt(f,te),ui(g.a,a),Vw(this,g,o,a,!0)))},h.zg=function(t){return t.i.n.b+t.n.b+t.a.b},h.Ag=function(){return Ct(),ar},h.Bg=function(){return Ct(),er},I(vfe,"WestToEastRoutingStrategy",1869),D(828,1,{},Ske),h.Ib=function(){return Tb(this.a)},h.b=0,h.c=!1,h.d=!1,h.f=0,I(Zy,"NubSpline",828),D(418,1,{418:1},dbt,rot),I(Zy,"NubSpline/PolarCP",418),D(1480,1,Uo,Ydt),h.rg=function(t){return gxn(l(t,36))},h.Kf=function(t,n){hIn(this,l(t,36),n)};var rTt,iTt,sTt,aTt,oTt;I(Zy,"SplineEdgeRouter",1480),D(274,1,{274:1},WH),h.Ib=function(){return this.a+" ->("+this.c+") "+this.b},h.c=0,I(Zy,"SplineEdgeRouter/Dependency",274),D(465,22,{3:1,34:1,22:1,465:1},H3e);var Hb,K6,cTt=Fr(Zy,"SplineEdgeRouter/SideToProcess",465,Hr,r2n,o1n),uTt;D(1481,1,ti,Ste),h.Mb=function(t){return GA(),!l(t,131).o},I(Zy,"SplineEdgeRouter/lambda$0$Type",1481),D(1482,1,{},_te),h.Ze=function(t){return GA(),l(t,131).v+1},I(Zy,"SplineEdgeRouter/lambda$1$Type",1482),D(1483,1,fr,Jet),h.Cd=function(t){Ldn(this.a,this.b,l(t,42))},I(Zy,"SplineEdgeRouter/lambda$2$Type",1483),D(1484,1,fr,Zet),h.Cd=function(t){Mdn(this.a,this.b,l(t,42))},I(Zy,"SplineEdgeRouter/lambda$3$Type",1484),D(131,1,{34:1,131:1},_pt,Ike),h.Fd=function(t){return Iun(this,l(t,131))},h.b=0,h.e=!1,h.f=0,h.g=0,h.j=!1,h.k=!1,h.n=0,h.o=!1,h.p=!1,h.q=!1,h.s=0,h.u=0,h.v=0,h.F=0,I(Zy,"SplineSegment",131),D(468,1,{468:1},Ate),h.a=0,h.b=!1,h.c=!1,h.d=!1,h.e=!1,h.f=0,I(Zy,"SplineSegment/EdgeInformation",468),D(1198,1,{},CS),I(gp,LEe,1198),D(1199,1,ii,Lte),h.Ne=function(t,n){return Xkn(l(t,121),l(n,121))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(gp,E3t,1199),D(1197,1,{},dZe),I(gp,"MrTree",1197),D(405,22,{3:1,34:1,22:1,405:1,188:1,196:1},vq),h.dg=function(){return Wpt(this)},h.qg=function(){return Wpt(this)};var NW,lM,hM,fM,qDe=Fr(gp,"TreeLayoutPhases",405,Hr,smn,c1n),lTt;D(1112,205,tv,Hrt),h.rf=function(t,n){var r,a,o,f,g,w,E,C;for(Rt(Bt(at(t,(Hc(),dIe))))||KO((r=new Yv((aw(),new Jv(t))),r)),g=n.eh(xfe),g.Ug("build tGraph",1),w=(E=new nN,pc(E,t),rt(E,(Qi(),gM),t),C=new Pr,H_n(t,E,C),cAn(t,E,C),E),g.Vg(),g=n.eh(xfe),g.Ug("Split graph",1),f=Y_n(this.a,w),g.Vg(),o=new G(f);o.a"+Bm(this.c):"e_"+es(this)},I(vL,"TEdge",65),D(121,137,{3:1,121:1,96:1,137:1},nN),h.Ib=function(){var t,n,r,a,o;for(o=null,a=Rr(this.b,0);a.b!=a.d.c;)r=l(Br(a),40),o+=(r.c==null||r.c.length==0?"n_"+r.g:"n_"+r.c)+` +`;for(n=Rr(this.a,0);n.b!=n.d.c;)t=l(Br(n),65),o+=(t.b&&t.c?Bm(t.b)+"->"+Bm(t.c):"e_"+es(t))+` +`;return o};var _On=I(vL,"TGraph",121);D(643,508,{3:1,508:1,643:1,96:1,137:1}),I(vL,"TShape",643),D(40,643,{3:1,508:1,40:1,643:1,96:1,137:1},xce),h.Ib=function(){return Bm(this)};var PW=I(vL,"TNode",40);D(236,1,hg,Hg),h.Jc=function(t){to(this,t)},h.Kc=function(){var t;return t=Rr(this.a.d,0),new C5(t)},I(vL,"TNode/2",236),D(329,1,Oa,C5),h.Nb=function(t){Za(this,t)},h.Pb=function(){return l(Br(this.a),65).c},h.Ob=function(){return QI(this.a)},h.Qb=function(){Yoe(this.a)},I(vL,"TNode/2/1",329),D(1923,1,ts,Bte),h.Kf=function(t,n){zIn(this,l(t,121),n)},I(Su,"CompactionProcessor",1923),D(1924,1,ii,lXe),h.Ne=function(t,n){return A3n(this.a,l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Su,"CompactionProcessor/lambda$0$Type",1924),D(1925,1,ti,ttt),h.Mb=function(t){return Npn(this.b,this.a,l(t,42))},h.a=0,h.b=0,I(Su,"CompactionProcessor/lambda$1$Type",1925),D(1934,1,ii,o8),h.Ne=function(t,n){return Cgn(l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Su,"CompactionProcessor/lambda$10$Type",1934),D(1935,1,ii,Zj),h.Ne=function(t,n){return jhn(l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Su,"CompactionProcessor/lambda$11$Type",1935),D(1936,1,ii,Fte),h.Ne=function(t,n){return Sgn(l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Su,"CompactionProcessor/lambda$12$Type",1936),D(1926,1,ti,hXe),h.Mb=function(t){return khn(this.a,l(t,42))},h.a=0,I(Su,"CompactionProcessor/lambda$2$Type",1926),D(1927,1,ti,fXe),h.Mb=function(t){return Ehn(this.a,l(t,42))},h.a=0,I(Su,"CompactionProcessor/lambda$3$Type",1927),D(1928,1,ti,pI),h.Mb=function(t){return l(t,40).c.indexOf(DG)==-1},I(Su,"CompactionProcessor/lambda$4$Type",1928),D(1929,1,{},dXe),h.Kb=function(t){return Bbn(this.a,l(t,40))},h.a=0,I(Su,"CompactionProcessor/lambda$5$Type",1929),D(1930,1,{},gXe),h.Kb=function(t){return Vvn(this.a,l(t,40))},h.a=0,I(Su,"CompactionProcessor/lambda$6$Type",1930),D(1931,1,ii,pXe),h.Ne=function(t,n){return tvn(this.a,l(t,240),l(n,240))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Su,"CompactionProcessor/lambda$7$Type",1931),D(1932,1,ii,bXe),h.Ne=function(t,n){return nvn(this.a,l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Su,"CompactionProcessor/lambda$8$Type",1932),D(1933,1,ii,Rte),h.Ne=function(t,n){return $hn(l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Su,"CompactionProcessor/lambda$9$Type",1933),D(1921,1,ts,jte),h.Kf=function(t,n){FSn(l(t,121),n)},I(Su,"DirectionProcessor",1921),D(1913,1,ts,qrt),h.Kf=function(t,n){aAn(this,l(t,121),n)},I(Su,"FanProcessor",1913),D(1937,1,ts,$te),h.Kf=function(t,n){CSn(l(t,121),n)},I(Su,"GraphBoundsProcessor",1937),D(1938,1,{},zte),h.Ye=function(t){return l(t,40).e.a},I(Su,"GraphBoundsProcessor/lambda$0$Type",1938),D(1939,1,{},qte),h.Ye=function(t){return l(t,40).e.b},I(Su,"GraphBoundsProcessor/lambda$1$Type",1939),D(1940,1,{},Hte),h.Ye=function(t){return sln(l(t,40))},I(Su,"GraphBoundsProcessor/lambda$2$Type",1940),D(1941,1,{},Vte),h.Ye=function(t){return iln(l(t,40))},I(Su,"GraphBoundsProcessor/lambda$3$Type",1941),D(262,22,{3:1,34:1,22:1,262:1,196:1},ow),h.dg=function(){switch(this.g){case 0:return new bJe;case 1:return new qrt;case 2:return new pJe;case 3:return new n$;case 4:return new Ute;case 8:return new e$;case 5:return new jte;case 6:return new i$;case 7:return new Bte;case 9:return new $te;case 10:return new Kte;default:throw ue(new Yn(Fhe+(this.f!=null?this.f:""+this.g)))}};var HDe,VDe,UDe,GDe,KDe,WDe,YDe,XDe,QDe,JDe,Dde,AOn=Fr(Su,Rhe,262,Hr,Bft,u1n),hTt;D(1920,1,ts,e$),h.Kf=function(t,n){RDn(l(t,121),n)},I(Su,"LevelCoordinatesProcessor",1920),D(1918,1,ts,Ute),h.Kf=function(t,n){sCn(this,l(t,121),n)},h.a=0,I(Su,"LevelHeightProcessor",1918),D(1919,1,hg,t$),h.Jc=function(t){to(this,t)},h.Kc=function(){return Cn(),Mk(),AT},I(Su,"LevelHeightProcessor/1",1919),D(1914,1,ts,pJe),h.Kf=function(t,n){wSn(this,l(t,121),n)},I(Su,"LevelProcessor",1914),D(1915,1,ti,Gte),h.Mb=function(t){return Rt(Bt(Q(l(t,40),(Qi(),Vb))))},I(Su,"LevelProcessor/lambda$0$Type",1915),D(1916,1,ts,n$),h.Kf=function(t,n){nkn(this,l(t,121),n)},h.a=0,I(Su,"NeighborsProcessor",1916),D(1917,1,hg,r$),h.Jc=function(t){to(this,t)},h.Kc=function(){return Cn(),Mk(),AT},I(Su,"NeighborsProcessor/1",1917),D(1922,1,ts,i$),h.Kf=function(t,n){sAn(this,l(t,121),n)},h.a=0,I(Su,"NodePositionProcessor",1922),D(1912,1,ts,bJe),h.Kf=function(t,n){$Ln(this,l(t,121),n)},I(Su,"RootProcessor",1912),D(1942,1,ts,Kte),h.Kf=function(t,n){B6n(l(t,121),n)},I(Su,"Untreeifyer",1942),D(392,22,{3:1,34:1,22:1,392:1},Ose);var OB,Ide,ZDe,eIe=Fr(UP,"EdgeRoutingMode",392,Hr,J2n,l1n),fTt,NB,QT,Ode,tIe,nIe,Nde,Pde,rIe,Bde,iIe,Fde,dM,Rde,BW,FW,k0,c1,JT,gM,pM,C2,sIe,dTt,jde,Vb,PB,BB;D(862,1,Pf,rie),h.hf=function(t){sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,fCe),""),pyt),"Turns on Tree compaction which decreases the size of the whole tree by placing nodes of multiple levels in one large level"),(Hn(),!1)),(g2(),ya)),Ns),un((r1(),Pn))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,dCe),""),"Edge End Texture Length"),"Should be set to the length of the texture at the end of an edge. This value can be used to improve the Edge Routing."),7),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,gCe),""),"Tree Level"),"The index for the tree level the node is in"),pt(0)),Tc),ro),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,pCe),""),pyt),"When set to a positive number this option will force the algorithm to place the node to the specified position within the trees layer if weighting is set to constraint"),pt(-1)),Tc),ro),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,bCe),""),"Weighting of Nodes"),"Which weighting to use when computing a node order."),cIe),ps),yIe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,mCe),""),"Edge Routing Mode"),"Chooses an Edge Routing algorithm."),aIe),ps),eIe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,vCe),""),"Search Order"),"Which search order to use when computing a spanning tree."),oIe),ps),kIe),un(Pn)))),iwt((new v8,t))};var gTt,pTt,bTt,aIe,mTt,vTt,oIe,wTt,yTt,cIe;I(UP,"MrTreeMetaDataProvider",862),D(1006,1,Pf,v8),h.hf=function(t){iwt(t)};var xTt,uIe,lIe,y3,hIe,fIe,$de,kTt,ETt,TTt,CTt,STt,_Tt,ATt,dIe,gIe,pIe,LTt,W6,RW,bIe,MTt,mIe,zde,DTt,ITt,OTt,vIe,NTt,$d,wIe;I(UP,"MrTreeOptions",1006),D(1007,1,{},Wte),h.sf=function(){var t;return t=new Hrt,t},h.tf=function(t){},I(UP,"MrTreeOptions/MrtreeFactory",1007),D(353,22,{3:1,34:1,22:1,353:1},wq);var qde,jW,Hde,Vde,yIe=Fr(UP,"OrderWeighting",353,Hr,amn,h1n),PTt;D(433,22,{3:1,34:1,22:1,433:1},V3e);var xIe,Ude,kIe=Fr(UP,"TreeifyingOrder",433,Hr,t2n,f1n),BTt;D(1486,1,Uo,aie),h.rg=function(t){return l(t,121),FTt},h.Kf=function(t,n){b3n(this,l(t,121),n)};var FTt;I("org.eclipse.elk.alg.mrtree.p1treeify","DFSTreeifyer",1486),D(1487,1,Uo,dk),h.rg=function(t){return l(t,121),RTt},h.Kf=function(t,n){ESn(this,l(t,121),n)};var RTt;I(pT,"NodeOrderer",1487),D(1494,1,{},pwe),h.td=function(t){return Yit(t)},I(pT,"NodeOrderer/0methodref$lambda$6$Type",1494),D(1488,1,ti,ane),h.Mb=function(t){return ux(),Rt(Bt(Q(l(t,40),(Qi(),Vb))))},I(pT,"NodeOrderer/lambda$0$Type",1488),D(1489,1,ti,one),h.Mb=function(t){return ux(),l(Q(l(t,40),(Hc(),W6)),17).a<0},I(pT,"NodeOrderer/lambda$1$Type",1489),D(1490,1,ti,vXe),h.Mb=function(t){return Uwn(this.a,l(t,40))},I(pT,"NodeOrderer/lambda$2$Type",1490),D(1491,1,ti,mXe),h.Mb=function(t){return jbn(this.a,l(t,40))},I(pT,"NodeOrderer/lambda$3$Type",1491),D(1492,1,ii,cne),h.Ne=function(t,n){return gwn(l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(pT,"NodeOrderer/lambda$4$Type",1492),D(1493,1,ti,une),h.Mb=function(t){return ux(),l(Q(l(t,40),(Qi(),Pde)),17).a!=0},I(pT,"NodeOrderer/lambda$5$Type",1493),D(1495,1,Uo,sie),h.rg=function(t){return l(t,121),jTt},h.Kf=function(t,n){I_n(this,l(t,121),n)},h.b=0;var jTt;I("org.eclipse.elk.alg.mrtree.p3place","NodePlacer",1495),D(1496,1,Uo,iie),h.rg=function(t){return l(t,121),$Tt},h.Kf=function(t,n){d_n(l(t,121),n)};var $Tt,LOn=I(vh,"EdgeRouter",1496);D(1498,1,ii,sne),h.Ne=function(t,n){return ru(l(t,17).a,l(n,17).a)},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/0methodref$compare$Type",1498),D(1503,1,{},Yte),h.Ye=function(t){return ze(Ge(t))},I(vh,"EdgeRouter/1methodref$doubleValue$Type",1503),D(1505,1,ii,a$),h.Ne=function(t,n){return Yi(ze(Ge(t)),ze(Ge(n)))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/2methodref$compare$Type",1505),D(1507,1,ii,Xte),h.Ne=function(t,n){return Yi(ze(Ge(t)),ze(Ge(n)))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/3methodref$compare$Type",1507),D(1509,1,{},s$),h.Ye=function(t){return ze(Ge(t))},I(vh,"EdgeRouter/4methodref$doubleValue$Type",1509),D(1511,1,ii,Qte),h.Ne=function(t,n){return Yi(ze(Ge(t)),ze(Ge(n)))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/5methodref$compare$Type",1511),D(1513,1,ii,bI),h.Ne=function(t,n){return Yi(ze(Ge(t)),ze(Ge(n)))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/6methodref$compare$Type",1513),D(1497,1,{},Jte),h.Kb=function(t){return tp(),l(Q(l(t,40),(Hc(),$d)),17)},I(vh,"EdgeRouter/lambda$0$Type",1497),D(1508,1,{},Zte),h.Kb=function(t){return Zhn(l(t,40))},I(vh,"EdgeRouter/lambda$11$Type",1508),D(1510,1,{},ntt),h.Kb=function(t){return _dn(this.b,this.a,l(t,40))},h.a=0,h.b=0,I(vh,"EdgeRouter/lambda$13$Type",1510),D(1512,1,{},rtt),h.Kb=function(t){return efn(this.b,this.a,l(t,40))},h.a=0,h.b=0,I(vh,"EdgeRouter/lambda$15$Type",1512),D(1514,1,ii,ene),h.Ne=function(t,n){return f6n(l(t,65),l(n,65))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/lambda$17$Type",1514),D(1515,1,ii,tne),h.Ne=function(t,n){return d6n(l(t,65),l(n,65))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/lambda$18$Type",1515),D(1516,1,ii,nne),h.Ne=function(t,n){return p6n(l(t,65),l(n,65))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/lambda$19$Type",1516),D(1499,1,ti,wXe),h.Mb=function(t){return b2n(this.a,l(t,40))},h.a=0,I(vh,"EdgeRouter/lambda$2$Type",1499),D(1517,1,ii,o$),h.Ne=function(t,n){return g6n(l(t,65),l(n,65))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/lambda$20$Type",1517),D(1500,1,ii,rne),h.Ne=function(t,n){return ddn(l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/lambda$3$Type",1500),D(1501,1,ii,ine),h.Ne=function(t,n){return gdn(l(t,40),l(n,40))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"EdgeRouter/lambda$4$Type",1501),D(1502,1,{},lne),h.Kb=function(t){return tfn(l(t,40))},I(vh,"EdgeRouter/lambda$5$Type",1502),D(1504,1,{},itt),h.Kb=function(t){return Adn(this.b,this.a,l(t,40))},h.a=0,h.b=0,I(vh,"EdgeRouter/lambda$7$Type",1504),D(1506,1,{},stt),h.Kb=function(t){return nfn(this.b,this.a,l(t,40))},h.a=0,h.b=0,I(vh,"EdgeRouter/lambda$9$Type",1506),D(675,1,{675:1},Fdt),h.e=0,h.f=!1,h.g=!1,I(vh,"MultiLevelEdgeNodeNodeGap",675),D(1943,1,ii,hne),h.Ne=function(t,n){return S2n(l(t,240),l(n,240))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"MultiLevelEdgeNodeNodeGap/lambda$0$Type",1943),D(1944,1,ii,fne),h.Ne=function(t,n){return _2n(l(t,240),l(n,240))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(vh,"MultiLevelEdgeNodeNodeGap/lambda$1$Type",1944);var Y6;D(501,22,{3:1,34:1,22:1,501:1,188:1,196:1},U3e),h.dg=function(){return E1t(this)},h.qg=function(){return E1t(this)};var $W,X6,EIe=Fr(wCe,"RadialLayoutPhases",501,Hr,Wpn,d1n),zTt;D(1113,205,tv,fZe),h.rf=function(t,n){var r,a,o,f,g,w;if(r=cbt(this,t),n.Ug("Radial layout",r.c.length),Rt(Bt(at(t,(Sb(),NIe))))||KO((a=new Yv((aw(),new Jv(t))),a)),w=mxn(t),Hi(t,(H5(),Y6),w),!w)throw ue(new Yn("The given graph is not a tree!"));for(o=ze(Ge(at(t,HW))),o==0&&(o=qpt(t)),Hi(t,HW,o),g=new G(cbt(this,t));g.a=3)for(ot=l(Oe($e,0),27),St=l(Oe($e,1),27),f=0;f+2<$e.i;)if(Ze=ot,ot=St,St=l(Oe($e,f+2),27),Ze.f>=ot.f+St.f+L||St.f>=Ze.f+ot.f+L){cn=!0;break}else++f;else cn=!0;if(!cn){for(z=$e.i,w=new or($e);w.e!=w.i.gc();)g=l(gr(w),27),Hi(g,(pi(),XB),pt(z)),--z;Rmt(t,new L8),n.Vg();return}for(r=(qO(this.a),X0(this.a,(WV(),RB),l(at(t,uOe),188)),X0(this.a,VW,l(at(t,rOe),188)),X0(this.a,rge,l(at(t,aOe),188)),uye(this.a,(Bn=new Xs,fi(Bn,RB,(sU(),age)),fi(Bn,VW,sge),Rt(Bt(at(t,tOe)))&&fi(Bn,RB,ige),Bn)),bP(this.a,t)),C=1/r.c.length,J=new G(r);J.a0&&K0t((Xn(n-1,t.length),t.charCodeAt(n-1)),N3t);)--n;if(a>=n)throw ue(new Yn("The given string does not contain any numbers."));if(o=Gy((Ga(a,n,t.length),t.substr(a,n-a)),`,|;|\r| +`),o.length!=2)throw ue(new Yn("Exactly two numbers are expected, "+o.length+" were found."));try{this.a=jy($y(o[0])),this.b=jy($y(o[1]))}catch(f){throw f=bs(f),De(f,130)?(r=f,ue(new Yn(P3t+r))):ue(f)}},h.Ib=function(){return"("+this.a+","+this.b+")"},h.a=0,h.b=0;var Ea=I($P,"KVector",8);D(75,67,{3:1,4:1,20:1,31:1,56:1,16:1,67:1,15:1,75:1,423:1},bl,Gz,frt),h.Pc=function(){return Oyn(this)},h.cg=function(t){var n,r,a,o,f,g;a=Gy(t,`,|;|\\(|\\)|\\[|\\]|\\{|\\}| | | +`),Ch(this);try{for(r=0,f=0,o=0,g=0;r0&&(f%2==0?o=jy(a[r]):g=jy(a[r]),f>0&&f%2!=0&&ui(this,new lt(o,g)),++f),++r}catch(w){throw w=bs(w),De(w,130)?(n=w,ue(new Yn("The given string does not match the expected format for vectors."+n))):ue(w)}},h.Ib=function(){var t,n,r;for(t=new Th("("),n=Rr(this,0);n.b!=n.d.c;)r=l(Br(n),8),hi(t,r.a+","+r.b),n.b!=n.d.c&&(t.a+="; ");return(t.a+=")",t).a};var GOe=I($P,"KVectorChain",75);D(255,22,{3:1,34:1,22:1,255:1},__);var Sge,eY,tY,HB,VB,nY,KOe=Fr(nh,"Alignment",255,Hr,Mvn,F1n),xSt;D(991,1,Pf,fie),h.hf=function(t){xmt(t)};var WOe,_ge,kSt,YOe,XOe,ESt,QOe,TSt,CSt,JOe,ZOe,SSt;I(nh,"BoxLayouterOptions",991),D(992,1,{},ek),h.sf=function(){var t;return t=new jne,t},h.tf=function(t){},I(nh,"BoxLayouterOptions/BoxFactory",992),D(298,22,{3:1,34:1,22:1,298:1},A_);var EM,Age,TM,CM,SM,Lge,Mge=Fr(nh,"ContentAlignment",298,Hr,Dvn,R1n),_St;D(699,1,Pf,uz),h.hf=function(t){sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,Byt),""),"Layout Algorithm"),"Select a specific layout algorithm."),(g2(),J6)),zt),un((r1(),Pn))))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,Fyt),""),"Resolved Layout Algorithm"),"Meta data associated with the selected algorithm."),X1),IOn),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,qTe),""),"Alignment"),"Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm."),eNe),ps),KOe),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,Ox),""),"Aspect Ratio"),"The desired aspect ratio of the drawing, that is the quotient of width by height."),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,tSe),""),"Bend Points"),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),X1),GOe),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,SG),""),"Content Alignment"),"Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option."),nNe),t9),Mge),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,VP),""),"Debug Mode"),"Whether additional debug information shall be generated."),(Hn(),!1)),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,gfe),""),kEe),"Overall direction of edges: horizontal (right / left) or vertical (down / up)."),rNe),ps),LM),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,HP),""),"Edge Routing"),"What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline."),aNe),ps),Vge),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ZCe),""),"Expand Nodes"),"If active, nodes are expanded to fill the area of their parent."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,CG),""),"Hierarchy Handling"),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),uNe),ps),YNe),rs(Pn,he(le(xg,1),it,170,0,[ha]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Xw),""),"Padding"),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),vNe),X1),wAe),rs(Pn,he(le(xg,1),it,170,0,[ha]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,hL),""),"Interactive"),"Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,AG),""),"interactive Layout"),"Whether the graph should be changeable interactively and by setting constraints"),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,fL),""),"Omit Node Micro Layout"),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Nhe),""),"Port Constraints"),"Defines constraints of the position of the ports of a node."),ENe),ps),JNe),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,_G),""),"Position"),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),X1),Ea),rs(ha,he(le(xg,1),it,170,0,[yv,S2]))))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,NP),""),"Priority"),"Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used."),Tc),ro),rs(ha,he(le(xg,1),it,170,0,[zd]))))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,oG),""),"Randomization Seed"),"Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time)."),Tc),ro),un(Pn)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,lL),""),"Separate Connected Components"),"Whether each connected component should be processed separately."),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ZTe),""),"Junction Points"),"This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order."),lNe),X1),GOe),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,nCe),""),"Comment Box"),"Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related."),!1),ya),Ns),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,rCe),""),"Hypernode"),"Whether the node should be handled as a hypernode."),!1),ya),Ns),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,sOn),""),"Label Manager"),"Label managers can shorten labels upon a layout algorithm's request."),X1),FOn),rs(Pn,he(le(xg,1),it,170,0,[S2]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,sCe),""),"Margins"),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),hNe),X1),vAe),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,$Te),""),"No Layout"),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),!1),ya),Ns),rs(ha,he(le(xg,1),it,170,0,[zd,yv,S2]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Ryt),""),"Scale Factor"),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),fo),ta),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,jyt),""),"Child Area Width"),"The width of the area occupied by the laid out children of a node."),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,$yt),""),"Child Area Height"),"The height of the area occupied by the laid out children of a node."),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,PP),""),Dyt),"Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by their parents. Graphs must follow a certain structure for topdown layout to work properly. {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set on the node itself rather than the parent. The values are then used by the size approximator as base values. Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to 'INCLUDE_CHILDREN'"),!1),ya),Ns),un(Pn)))),Qs(t,PP,Qw,null),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,zyt),""),"Animate"),"Whether the shift from the old layout to the new computed layout shall be animated."),!0),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,qyt),""),"Animation Time Factor"),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),pt(100)),Tc),ro),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Hyt),""),"Layout Ancestors"),"Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Vyt),""),"Maximal Animation Time"),"The maximal time for animations, in milliseconds."),pt(4e3)),Tc),ro),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Uyt),""),"Minimal Animation Time"),"The minimal time for animations, in milliseconds."),pt(400)),Tc),ro),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Gyt),""),"Progress Bar"),"Whether a progress bar shall be displayed during layout computations."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Kyt),""),"Validate Graph"),"Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Wyt),""),"Validate Options"),"Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!0),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Yyt),""),"Zoom to Fit"),"Whether the zoom level shall be set to view the whole diagram after layout."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,eSe),"box"),"Box Layout Mode"),"Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better."),tNe),ps),cPe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,LTe),U1),"Comment Comment Spacing"),"Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing."),10),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,MTe),U1),"Comment Node Spacing"),"Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing."),10),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,_he),U1),"Components Spacing"),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,DTe),U1),"Edge Spacing"),"Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines."),10),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Ohe),U1),"Edge Label Spacing"),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,dfe),U1),"Edge Node Spacing"),"Spacing to be preserved between nodes and edges."),10),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,ITe),U1),"Label Spacing"),"Determines the amount of space to be left between two labels of the same graph element."),0),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,PTe),U1),"Label Node Spacing"),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,OTe),U1),"Horizontal spacing between Label and Port"),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,NTe),U1),"Vertical spacing between Label and Port"),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Jy),U1),"Node Spacing"),"The minimal distance to be preserved between each two nodes."),20),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,BTe),U1),"Node Self Loop Spacing"),"Spacing to be preserved between a node and its self loops."),10),fo),ta),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,FTe),U1),"Port Spacing"),"Spacing between pairs of ports of the same node."),10),fo),ta),rs(Pn,he(le(xg,1),it,170,0,[ha]))))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,RTe),U1),"Individual Spacing"),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),X1),g_t),rs(ha,he(le(xg,1),it,170,0,[zd,yv,S2]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,aCe),U1),"Additional Port Space"),"Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border."),NNe),X1),vAe),un(Pn)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,bfe),Jyt),"Layout Partition"),"Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction)."),Tc),ro),rs(Pn,he(le(xg,1),it,170,0,[ha]))))),Qs(t,bfe,pfe,BSt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,pfe),Jyt),"Layout Partitioning"),"Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle."),wNe),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,UTe),Zyt),"Node Label Padding"),"Define padding for node labels that are placed inside of a node."),dNe),X1),wAe),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,fT),Zyt),"Node Label Placement"),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),gNe),t9),Ko),rs(ha,he(le(xg,1),it,170,0,[S2]))))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,WTe),RG),"Port Alignment"),"Defines the default port distribution for a node. May be overridden for each side individually."),xNe),ps),OM),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,YTe),RG),"Port Alignment (North)"),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),ps),OM),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,XTe),RG),"Port Alignment (South)"),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),ps),OM),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,QTe),RG),"Port Alignment (West)"),"Defines how ports on the western side are placed, overriding the node's general port alignment."),ps),OM),un(ha)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,JTe),RG),"Port Alignment (East)"),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),ps),OM),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,x6),Rfe),"Node Size Constraints"),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),pNe),t9),BM),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Nx),Rfe),"Node Size Options"),"Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications."),mNe),t9),ePe),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Px),Rfe),"Node Size Minimum"),"The minimal size to which a node can be reduced."),bNe),X1),Ea),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,hT),Rfe),"Fixed Graph Size"),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),!1),ya),Ns),un(Pn)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,eCe),ffe),"Edge Label Placement"),"Gives a hint on where to put edge labels."),iNe),ps),FNe),un(S2)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,cG),ffe),"Inline Edge Labels"),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),!1),ya),Ns),un(S2)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,aOn),"font"),"Font Name"),"Font name used for a label."),J6),zt),un(S2)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,Xyt),"font"),"Font Size"),"Font size used for a label."),Tc),ro),un(S2)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,iCe),jfe),"Port Anchor Offset"),"The offset to the port position where connections shall be attached."),X1),Ea),un(yv)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,tCe),jfe),"Port Index"),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),Tc),ro),un(yv)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,zTe),jfe),"Port Side"),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),SNe),ps),Oo),un(yv)))),sn(t,new Xt(nn(tn(rn(Qt(en(Jt(Zt(new Ut,jTe),jfe),"Port Border Offset"),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),fo),ta),un(yv)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,dT),iSe),"Port Label Placement"),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),TNe),t9),cY),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,GTe),iSe),"Port Labels Next to Port"),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),!1),ya),Ns),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,KTe),iSe),"Treat Port Labels as Group"),"If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port."),!0),ya),Ns),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,BP),KP),"Topdown Scale Factor"),"The scaling factor to be applied to the nodes laid out within the node in recursive topdown layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on hierarchical nodes."),1),fo),ta),un(Pn)))),Qs(t,BP,Qw,VSt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,nSe),KP),"Topdown Size Approximator"),"The size approximator to be used to set sizes of hierarchical nodes during topdown layout. The default value is null, which results in nodes keeping whatever size is defined for them e.g. through parent parallel node or by manually setting the size."),null),ps),gY),un(ha)))),Qs(t,nSe,Qw,USt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,FP),KP),"Topdown Hierarchical Node Width"),"The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself."),150),fo),ta),rs(Pn,he(le(xg,1),it,170,0,[ha]))))),Qs(t,FP,Qw,null),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,RP),KP),"Topdown Hierarchical Node Aspect Ratio"),"The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself."),1.414),fo),ta),rs(Pn,he(le(xg,1),it,170,0,[ha]))))),Qs(t,RP,Qw,null),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Qw),KP),"Topdown Node Type"),"The different node types used for topdown layout. If the node type is set to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for hierarchical nodes."),null),ps),nPe),un(ha)))),Qs(t,Qw,hT,null),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,rSe),KP),"Topdown Scale Cap"),"Determines the upper limit for the topdown scale factor. The default value is 1.0 which ensures that nested children never end up appearing larger than their parents in terms of unit sizes such as the font size. If the limit is larger, nodes will fully utilize the available space, but it is counteriniuitive for inner nodes to have a larger scale than outer nodes."),1),fo),ta),un(Pn)))),Qs(t,rSe,Qw,HSt),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,HTe),e4t),"Activate Inside Self Loops"),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),!1),ya),Ns),un(ha)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,VTe),e4t),"Inside Self Loop"),"Whether a self loop should be routed inside a node instead of around that node."),!1),ya),Ns),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Ahe),"edge"),"Edge Thickness"),"The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it."),1),fo),ta),un(zd)))),sn(t,new Xt(nn(tn(rn(yn(Qt(en(Jt(Zt(new Ut,Qyt),"edge"),"Edge Type"),"The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations."),cNe),ps),HNe),un(zd)))),m_(t,new nx(f_(Ck(Tk(new ny,sr),"Layered"),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.'))),m_(t,new nx(f_(Ck(Tk(new ny,"org.eclipse.elk.orthogonal"),"Orthogonal"),`Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia '86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.`))),m_(t,new nx(f_(Ck(Tk(new ny,Yu),"Force"),"Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984."))),m_(t,new nx(f_(Ck(Tk(new ny,"org.eclipse.elk.circle"),"Circle"),"Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph."))),m_(t,new nx(f_(Ck(Tk(new ny,byt),"Tree"),"Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type."))),m_(t,new nx(f_(Ck(Tk(new ny,"org.eclipse.elk.planar"),"Planar"),"Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable."))),m_(t,new nx(f_(Ck(Tk(new ny,gf),"Radial"),"Radial layout algorithms usually position the nodes of the graph on concentric circles."))),amt((new die,t)),xmt((new fie,t)),Nbt((new lz,t))};var eC,ASt,eNe,Z6,LSt,MSt,tNe,e7,t7,DSt,UB,nNe,GB,xv,rNe,Dge,Ige,iNe,sNe,aNe,oNe,cNe,ISt,n7,uNe,OSt,KB,Oge,WB,Nge,x3,lNe,tC,hNe,fNe,dNe,r7,gNe,kv,pNe,C4,i7,bNe,Ub,mNe,rY,YB,_2,vNe,NSt,wNe,PSt,BSt,yNe,xNe,Pge,Bge,Fge,Rge,kNe,rh,_M,ENe,jge,$ge,S4,TNe,CNe,s7,SNe,n9,XB,zge,a7,FSt,qge,RSt,jSt,_Ne,$St,ANe,LNe,r9,MNe,iY,DNe,INe,Ev,zSt,ONe,NNe,PNe,sY,QB,AM,i9,qSt,HSt,aY,VSt,BNe,USt;I(nh,"CoreOptions",699),D(88,22,{3:1,34:1,22:1,88:1},mO);var Q1,uc,vc,J1,wf,LM=Fr(nh,kEe,88,Hr,Pmn,j1n),GSt;D(278,22,{3:1,34:1,22:1,278:1},zse);var nC,_4,rC,FNe=Fr(nh,"EdgeLabelPlacement",278,Hr,lbn,$1n),KSt;D(223,22,{3:1,34:1,22:1,223:1},xq);var iC,JB,s9,Hge,Vge=Fr(nh,"EdgeRouting",223,Hr,lmn,z1n),WSt;D(321,22,{3:1,34:1,22:1,321:1},L_);var RNe,jNe,$Ne,zNe,Uge,qNe,HNe=Fr(nh,"EdgeType",321,Hr,Lvn,q1n),YSt;D(989,1,Pf,die),h.hf=function(t){amt(t)};var VNe,UNe,GNe,KNe,XSt,WNe,MM;I(nh,"FixedLayouterOptions",989),D(990,1,{},v$),h.sf=function(){var t;return t=new Une,t},h.tf=function(t){},I(nh,"FixedLayouterOptions/FixedFactory",990),D(346,22,{3:1,34:1,22:1,346:1},qse);var A2,oY,DM,YNe=Fr(nh,"HierarchyHandling",346,Hr,cbn,H1n),QSt;D(291,22,{3:1,34:1,22:1,291:1},kq);var kg,Gb,ZB,eF,JSt=Fr(nh,"LabelSide",291,Hr,umn,V1n),ZSt;D(95,22,{3:1,34:1,22:1,95:1},D5);var mp,E0,zf,T0,jh,C0,qf,Eg,S0,Ko=Fr(nh,"NodeLabelPlacement",95,Hr,Mwn,U1n),e_t;D(256,22,{3:1,34:1,22:1,256:1},vO);var XNe,IM,Kb,QNe,tF,OM=Fr(nh,"PortAlignment",256,Hr,Xmn,G1n),t_t;D(101,22,{3:1,34:1,22:1,101:1},M_);var Tv,Mu,Tg,sC,Z1,Wb,JNe=Fr(nh,"PortConstraints",101,Hr,Avn,K1n),n_t;D(279,22,{3:1,34:1,22:1,279:1},D_);var NM,PM,vp,nF,Yb,a9,cY=Fr(nh,"PortLabelPlacement",279,Hr,_vn,W1n),r_t;D(64,22,{3:1,34:1,22:1,64:1},wO);var ar,Qn,yf,xf,ll,Ju,ed,_0,zl,_l,Du,ql,hl,fl,A0,$h,zh,Hf,Dr,Pc,er,Oo=Fr(nh,"PortSide",64,Hr,Bmn,Y1n),i_t;D(993,1,Pf,lz),h.hf=function(t){Nbt(t)};var s_t,a_t,ZNe,o_t,c_t;I(nh,"RandomLayouterOptions",993),D(994,1,{},w$),h.sf=function(){var t;return t=new qne,t},h.tf=function(t){},I(nh,"RandomLayouterOptions/RandomFactory",994),D(386,22,{3:1,34:1,22:1,386:1},Eq);var A4,rF,iF,Cv,BM=Fr(nh,"SizeConstraint",386,Hr,cmn,X1n),u_t;D(264,22,{3:1,34:1,22:1,264:1},I5);var sF,uY,aC,Gge,aF,FM,lY,hY,fY,ePe=Fr(nh,"SizeOptions",264,Hr,qwn,Q1n),l_t;D(280,22,{3:1,34:1,22:1,280:1},Hse);var L4,tPe,dY,nPe=Fr(nh,"TopdownNodeTypes",280,Hr,hbn,J1n),h_t;D(347,22,sSe);var rPe,iPe,gY=Fr(nh,"TopdownSizeApproximator",347,Hr,a2n,edn);D(987,347,sSe,Wit),h.Tg=function(t){return Tdt(t)},Fr(nh,"TopdownSizeApproximator/1",987,gY,null,null),D(988,347,sSe,Ost),h.Tg=function(t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an,Bn;for(n=l(at(t,(pi(),a7)),143),St=(rb(),V=new a_,V),aP(St,t),cn=new Pr,f=new or((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a));f.e!=f.i.gc();)a=l(gr(f),27),Me=(z=new a_,z),LU(Me,St),aP(Me,a),Bn=Tdt(a),F5(Me,b.Math.max(a.g,Bn.a),b.Math.max(a.f,Bn.b)),ju(cn.f,a,Me);for(o=new or((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a));o.e!=o.i.gc();)for(a=l(gr(o),27),L=new or((!a.e&&(a.e=new Ln(js,a,7,4)),a.e));L.e!=L.i.gc();)C=l(gr(L),74),Ze=l(hc(zo(cn.f,a)),27),ot=l(cr(cn,Oe((!C.c&&(C.c=new Ln(_r,C,5,8)),C.c),0)),27),$e=(B=new TI,B),qr((!$e.b&&($e.b=new Ln(_r,$e,4,7)),$e.b),Ze),qr((!$e.c&&($e.c=new Ln(_r,$e,5,8)),$e.c),ot),AU($e,ds(Ze)),aP($e,C);te=l(GO(n.f),205);try{te.rf(St,new x$),lat(n.f,te)}catch(jn){throw jn=bs(jn),De(jn,103)?(J=jn,ue(J)):ue(jn)}return P1(St,t7)||P1(St,e7)||Uke(St),E=ze(Ge(at(St,t7))),w=ze(Ge(at(St,e7))),g=E/w,r=ze(Ge(at(St,QB)))*b.Math.sqrt((!St.a&&(St.a=new nt(Ai,St,10,11)),St.a).i),an=l(at(St,_2),107),Te=an.b+an.c+1,fe=an.d+an.a+1,new lt(b.Math.max(Te,r),b.Math.max(fe,r/g))},Fr(nh,"TopdownSizeApproximator/2",988,gY,null,null);var f_t;D(344,1,{871:1},L8),h.Ug=function(t,n){return Fgt(this,t,n)},h.Vg=function(){apt(this)},h.Wg=function(){return this.q},h.Xg=function(){return this.f?ioe(this.f):null},h.Yg=function(){return ioe(this.a)},h.Zg=function(){return this.p},h.$g=function(){return!1},h._g=function(){return this.n},h.ah=function(){return this.p!=null&&!this.b},h.bh=function(t){var n;this.n&&(n=t,vt(this.f,n))},h.dh=function(t,n){var r,a;this.n&&t&&Sbn(this,(r=new Ust,a=cle(r,t),oDn(r),a),(NV(),Wge))},h.eh=function(t){var n;return this.b?null:(n=hwn(this,this.g),ui(this.a,n),n.i=this,this.d=t,n)},h.fh=function(t){t>0&&!this.b&&c7e(this,t)},h.b=!1,h.c=0,h.d=-1,h.e=null,h.f=null,h.g=-1,h.j=!1,h.k=!1,h.n=!1,h.o=0,h.q=0,h.r=0,I(Uc,"BasicProgressMonitor",344),D(717,205,tv,jne),h.rf=function(t,n){Rmt(t,n)},I(Uc,"BoxLayoutProvider",717),D(983,1,ii,DXe),h.Ne=function(t,n){return oCn(this,l(t,27),l(n,27))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},h.a=!1,I(Uc,"BoxLayoutProvider/1",983),D(163,1,{163:1},hV,vrt),h.Ib=function(){return this.c?oke(this.c):Tb(this.b)},I(Uc,"BoxLayoutProvider/Group",163),D(320,22,{3:1,34:1,22:1,320:1},Tq);var sPe,aPe,oPe,Kge,cPe=Fr(Uc,"BoxLayoutProvider/PackingMode",320,Hr,hmn,tdn),d_t;D(984,1,ii,tk),h.Ne=function(t,n){return Spn(l(t,163),l(n,163))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Uc,"BoxLayoutProvider/lambda$0$Type",984),D(985,1,ii,nk),h.Ne=function(t,n){return vpn(l(t,163),l(n,163))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Uc,"BoxLayoutProvider/lambda$1$Type",985),D(986,1,ii,y$),h.Ne=function(t,n){return wpn(l(t,163),l(n,163))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(Uc,"BoxLayoutProvider/lambda$2$Type",986),D(1384,1,{845:1},$ne),h.Mg=function(t,n){return tq(),!De(n,167)||mZe((hx(),l(t,167)),n)},I(Uc,"ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type",1384),D(1385,1,fr,IXe),h.Cd=function(t){Byn(this.a,l(t,149))},I(Uc,"ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type",1385),D(1386,1,fr,Hne),h.Cd=function(t){l(t,96),tq()},I(Uc,"ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type",1386),D(1390,1,fr,OXe),h.Cd=function(t){i3n(this.a,l(t,96))},I(Uc,"ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type",1390),D(1388,1,ti,utt),h.Mb=function(t){return myn(this.a,this.b,l(t,149))},I(Uc,"ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type",1388),D(1387,1,ti,ltt),h.Mb=function(t){return Jhn(this.a,this.b,l(t,845))},I(Uc,"ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type",1387),D(1389,1,fr,htt),h.Cd=function(t){hgn(this.a,this.b,l(t,149))},I(Uc,"ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type",1389),D(947,1,{},Vne),h.Kb=function(t){return ant(t)},h.Fb=function(t){return this===t},I(Uc,"ElkUtil/lambda$0$Type",947),D(948,1,fr,ftt),h.Cd=function(t){lEn(this.a,this.b,l(t,74))},h.a=0,h.b=0,I(Uc,"ElkUtil/lambda$1$Type",948),D(949,1,fr,dtt),h.Cd=function(t){tun(this.a,this.b,l(t,166))},h.a=0,h.b=0,I(Uc,"ElkUtil/lambda$2$Type",949),D(950,1,fr,gtt),h.Cd=function(t){Xln(this.a,this.b,l(t,135))},h.a=0,h.b=0,I(Uc,"ElkUtil/lambda$3$Type",950),D(951,1,fr,NXe),h.Cd=function(t){Idn(this.a,l(t,377))},I(Uc,"ElkUtil/lambda$4$Type",951),D(325,1,{34:1,325:1},Dcn),h.Fd=function(t){return Chn(this,l(t,242))},h.Fb=function(t){var n;return De(t,325)?(n=l(t,325),this.a==n.a):!1},h.Hb=function(){return ua(this.a)},h.Ib=function(){return this.a+" (exclusive)"},h.a=0,I(Uc,"ExclusiveBounds/ExclusiveLowerBound",325),D(1119,205,tv,Une),h.rf=function(t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te,Me,$e,Ze,ot,St,cn,an;for(n.Ug("Fixed Layout",1),f=l(at(t,(pi(),sNe)),223),B=0,z=0,Me=new or((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a));Me.e!=Me.i.gc();){for(fe=l(gr(Me),27),an=l(at(fe,(PV(),MM)),8),an&&(Qh(fe,an.a,an.b),l(at(fe,UNe),181).Hc((mh(),A4))&&(V=l(at(fe,KNe),8),V.a>0&&V.b>0&&Gw(fe,V.a,V.b,!0,!0))),B=b.Math.max(B,fe.i+fe.g),z=b.Math.max(z,fe.j+fe.f),C=new or((!fe.n&&(fe.n=new nt(ec,fe,1,7)),fe.n));C.e!=C.i.gc();)w=l(gr(C),135),an=l(at(w,MM),8),an&&Qh(w,an.a,an.b),B=b.Math.max(B,fe.i+w.i+w.g),z=b.Math.max(z,fe.j+w.j+w.f);for(ot=new or((!fe.c&&(fe.c=new nt(Hl,fe,9,9)),fe.c));ot.e!=ot.i.gc();)for(Ze=l(gr(ot),123),an=l(at(Ze,MM),8),an&&Qh(Ze,an.a,an.b),St=fe.i+Ze.i,cn=fe.j+Ze.j,B=b.Math.max(B,St+Ze.g),z=b.Math.max(z,cn+Ze.f),E=new or((!Ze.n&&(Ze.n=new nt(ec,Ze,1,7)),Ze.n));E.e!=E.i.gc();)w=l(gr(E),135),an=l(at(w,MM),8),an&&Qh(w,an.a,an.b),B=b.Math.max(B,St+w.i+w.g),z=b.Math.max(z,cn+w.j+w.f);for(o=new hr(dr(cp(fe).a.Kc(),new j));jr(o);)r=l(xr(o),74),L=Jvt(r),B=b.Math.max(B,L.a),z=b.Math.max(z,L.b);for(a=new hr(dr(sP(fe).a.Kc(),new j));jr(a);)r=l(xr(a),74),ds(cg(r))!=t&&(L=Jvt(r),B=b.Math.max(B,L.a),z=b.Math.max(z,L.b))}if(f==(ip(),iC))for(Te=new or((!t.a&&(t.a=new nt(Ai,t,10,11)),t.a));Te.e!=Te.i.gc();)for(fe=l(gr(Te),27),a=new hr(dr(cp(fe).a.Kc(),new j));jr(a);)r=l(xr(a),74),g=fAn(r),g.b==0?Hi(r,x3,null):Hi(r,x3,g);Rt(Bt(at(t,(PV(),GNe))))||($e=l(at(t,XSt),107),te=B+$e.b+$e.c,J=z+$e.d+$e.a,Gw(t,te,J,!0,!0)),n.Vg()},I(Uc,"FixedLayoutProvider",1119),D(385,137,{3:1,423:1,385:1,96:1,137:1},EI,Xlt),h.cg=function(t){var n,r,a,o,f,g,w,E,C;if(t)try{for(E=Gy(t,";,;"),f=E,g=0,w=f.length;g>16&Zs|n^a<<16},h.Kc=function(){return new PXe(this)},h.Ib=function(){return this.a==null&&this.b==null?"pair(null,null)":this.a==null?"pair(null,"+xc(this.b)+")":this.b==null?"pair("+xc(this.a)+",null)":"pair("+xc(this.a)+","+xc(this.b)+")"},I(Uc,"Pair",42),D(995,1,Oa,PXe),h.Nb=function(t){Za(this,t)},h.Ob=function(){return!this.c&&(!this.b&&this.a.a!=null||this.a.b!=null)},h.Pb=function(){if(!this.c&&!this.b&&this.a.a!=null)return this.b=!0,this.a.a;if(!this.c&&this.a.b!=null)return this.c=!0,this.a.b;throw ue(new _c)},h.Qb=function(){throw this.c&&this.a.b!=null?this.a.b=null:this.b&&this.a.a!=null&&(this.a.a=null),ue(new pl)},h.b=!1,h.c=!1,I(Uc,"Pair/1",995),D(455,1,{455:1},Sat),h.Fb=function(t){return Jc(this.a,l(t,455).a)&&Jc(this.c,l(t,455).c)&&Jc(this.d,l(t,455).d)&&Jc(this.b,l(t,455).b)},h.Hb=function(){return MN(he(le(wa,1),Rn,1,5,[this.a,this.c,this.d,this.b]))},h.Ib=function(){return"("+this.a+Co+this.c+Co+this.d+Co+this.b+")"},I(Uc,"Quadruple",455),D(1108,205,tv,qne),h.rf=function(t,n){var r,a,o,f,g;if(n.Ug("Random Layout",1),(!t.a&&(t.a=new nt(Ai,t,10,11)),t.a).i==0){n.Vg();return}f=l(at(t,(B8e(),o_t)),17),f&&f.a!=0?o=new VH(f.a):o=new Uce,r=XI(Ge(at(t,s_t))),g=XI(Ge(at(t,c_t))),a=l(at(t,a_t),107),MDn(t,o,r,g,a),n.Vg()},I(Uc,"RandomLayoutProvider",1108),D(240,1,{240:1},wae),h.Fb=function(t){return Jc(this.a,l(t,240).a)&&Jc(this.b,l(t,240).b)&&Jc(this.c,l(t,240).c)},h.Hb=function(){return MN(he(le(wa,1),Rn,1,5,[this.a,this.b,this.c]))},h.Ib=function(){return"("+this.a+Co+this.b+Co+this.c+")"},I(Uc,"Triple",240);var m_t;D(562,1,{}),h.Lf=function(){return new lt(this.f.i,this.f.j)},h.of=function(t){return eot(t,(pi(),rh))?at(this.f,v_t):at(this.f,t)},h.Mf=function(){return new lt(this.f.g,this.f.f)},h.Nf=function(){return this.g},h.pf=function(t){return P1(this.f,t)},h.Of=function(t){Uu(this.f,t.a),Gu(this.f,t.b)},h.Pf=function(t){Dw(this.f,t.a),Mw(this.f,t.b)},h.Qf=function(t){this.g=t},h.g=0;var v_t;I(xL,"ElkGraphAdapters/AbstractElkGraphElementAdapter",562),D(563,1,{853:1},Oz),h.Rf=function(){var t,n;if(!this.b)for(this.b=$H(EH(this.a).i),n=new or(EH(this.a));n.e!=n.i.gc();)t=l(gr(n),135),vt(this.b,new Yie(t));return this.b},h.b=null,I(xL,"ElkGraphAdapters/ElkEdgeAdapter",563),D(289,562,{},Jv),h.Sf=function(){return Gdt(this)},h.a=null,I(xL,"ElkGraphAdapters/ElkGraphAdapter",289),D(640,562,{187:1},Yie),I(xL,"ElkGraphAdapters/ElkLabelAdapter",640),D(639,562,{695:1},rae),h.Rf=function(){return m7n(this)},h.Vf=function(){var t;return t=l(at(this.f,(pi(),tC)),140),!t&&(t=new s_),t},h.Xf=function(){return v7n(this)},h.Zf=function(t){var n;n=new xae(t),Hi(this.f,(pi(),tC),n)},h.$f=function(t){Hi(this.f,(pi(),_2),new S4e(t))},h.Tf=function(){return this.d},h.Uf=function(){var t,n;if(!this.a)for(this.a=new bt,n=new hr(dr(sP(l(this.f,27)).a.Kc(),new j));jr(n);)t=l(xr(n),74),vt(this.a,new Oz(t));return this.a},h.Wf=function(){var t,n;if(!this.c)for(this.c=new bt,n=new hr(dr(cp(l(this.f,27)).a.Kc(),new j));jr(n);)t=l(xr(n),74),vt(this.c,new Oz(t));return this.c},h.Yf=function(){return AH(l(this.f,27)).i!=0||Rt(Bt(l(this.f,27).of((pi(),KB))))},h._f=function(){Xvn(this,(aw(),m_t))},h.a=null,h.b=null,h.c=null,h.d=null,h.e=null,I(xL,"ElkGraphAdapters/ElkNodeAdapter",639),D(1284,562,{852:1},BXe),h.Rf=function(){return S7n(this)},h.Uf=function(){var t,n;if(!this.a)for(this.a=eg(l(this.f,123).hh().i),n=new or(l(this.f,123).hh());n.e!=n.i.gc();)t=l(gr(n),74),vt(this.a,new Oz(t));return this.a},h.Wf=function(){var t,n;if(!this.c)for(this.c=eg(l(this.f,123).ih().i),n=new or(l(this.f,123).ih());n.e!=n.i.gc();)t=l(gr(n),74),vt(this.c,new Oz(t));return this.c},h.ag=function(){return l(l(this.f,123).of((pi(),s7)),64)},h.bg=function(){var t,n,r,a,o,f,g,w;for(a=M1(l(this.f,123)),r=new or(l(this.f,123).ih());r.e!=r.i.gc();)for(t=l(gr(r),74),w=new or((!t.c&&(t.c=new Ln(_r,t,5,8)),t.c));w.e!=w.i.gc();){if(g=l(gr(w),84),Ly(bc(g),a))return!0;if(bc(g)==a&&Rt(Bt(at(t,(pi(),Oge)))))return!0}for(n=new or(l(this.f,123).hh());n.e!=n.i.gc();)for(t=l(gr(n),74),f=new or((!t.b&&(t.b=new Ln(_r,t,4,7)),t.b));f.e!=f.i.gc();)if(o=l(gr(f),84),Ly(bc(o),a))return!0;return!1},h.a=null,h.b=null,h.c=null,I(xL,"ElkGraphAdapters/ElkPortAdapter",1284),D(1285,1,ii,zne),h.Ne=function(t,n){return i_n(l(t,123),l(n,123))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(xL,"ElkGraphAdapters/PortComparator",1285);var Xb=ks(pf,"EObject"),oC=ks(T6,r4t),qh=ks(T6,i4t),oF=ks(T6,s4t),cF=ks(T6,"ElkShape"),_r=ks(T6,a4t),js=ks(T6,aSe),cs=ks(T6,o4t),uF=ks(pf,c4t),RM=ks(pf,"EFactory"),w_t,Yge=ks(pf,u4t),u1=ks(pf,"EPackage"),La,y_t,x_t,fPe,pY,k_t,dPe,gPe,pPe,Cg,E_t,T_t,ec=ks(T6,oSe),Ai=ks(T6,cSe),Hl=ks(T6,uSe);D(93,1,l4t),h.th=function(){return this.uh(),null},h.uh=function(){return null},h.vh=function(){return this.uh(),!1},h.wh=function(){return!1},h.xh=function(t){Ni(this,t)},I(Rx,"BasicNotifierImpl",93),D(99,93,g4t),h.Yh=function(){return hh(this)},h.yh=function(t,n){return t},h.zh=function(){throw ue(new Qr)},h.Ah=function(t){var n;return n=Ro(l(Mn(this.Dh(),this.Fh()),19)),this.Ph().Th(this,n.n,n.f,t)},h.Bh=function(t,n){throw ue(new Qr)},h.Ch=function(t,n,r){return Nh(this,t,n,r)},h.Dh=function(){var t;return this.zh()&&(t=this.zh().Nk(),t)?t:this.ii()},h.Eh=function(){return Uue(this)},h.Fh=function(){throw ue(new Qr)},h.Gh=function(){var t,n;return n=this.$h().Ok(),!n&&this.zh().Tk(n=(w_(),t=j5e(Sd(this.Dh())),t==null?rpe:new TO(this,t))),n},h.Hh=function(t,n){return t},h.Ih=function(t){var n;return n=t.pk(),n?t.Lj():ms(this.Dh(),t)},h.Jh=function(){var t;return t=this.zh(),t?t.Qk():null},h.Kh=function(){return this.zh()?this.zh().Nk():null},h.Lh=function(t,n,r){return rU(this,t,n,r)},h.Mh=function(t){return tE(this,t)},h.Nh=function(t,n){return Moe(this,t,n)},h.Oh=function(){var t;return t=this.zh(),!!t&&t.Rk()},h.Ph=function(){throw ue(new Qr)},h.Qh=function(){return XV(this)},h.Rh=function(t,n,r,a){return mx(this,t,n,a)},h.Sh=function(t,n,r){var a;return a=l(Mn(this.Dh(),n),69),a.wk().zk(this,this.hi(),n-this.ji(),t,r)},h.Th=function(t,n,r,a){return IH(this,t,n,a)},h.Uh=function(t,n,r){var a;return a=l(Mn(this.Dh(),n),69),a.wk().Ak(this,this.hi(),n-this.ji(),t,r)},h.Vh=function(){return!!this.zh()&&!!this.zh().Pk()},h.Wh=function(t){return nue(this,t)},h.Xh=function(t){return got(this,t)},h.Zh=function(t){return Bvt(this,t)},h.$h=function(){throw ue(new Qr)},h._h=function(){return this.zh()?this.zh().Pk():null},h.ai=function(){return XV(this)},h.bi=function(t,n){$ue(this,t,n)},h.ci=function(t){this.$h().Sk(t)},h.di=function(t){this.$h().Vk(t)},h.ei=function(t){this.$h().Uk(t)},h.fi=function(t,n){var r,a,o,f;return f=this.Jh(),f&&t&&(n=To(f.El(),this,n),f.Il(this)),a=this.Ph(),a&&(sle(this,this.Ph(),this.Fh()).Bb&Io?(o=a.Qh(),o&&(t?!f&&o.Il(this):o.Hl(this))):(n=(r=this.Fh(),r>=0?this.Ah(n):this.Ph().Th(this,-1-r,null,n)),n=this.Ch(null,-1,n))),this.di(t),n},h.gi=function(t){var n,r,a,o,f,g,w,E;if(r=this.Dh(),f=ms(r,t),n=this.ji(),f>=n)return l(t,69).wk().Dk(this,this.hi(),f-n);if(f<=-1)if(g=g6((El(),io),r,t),g){if(Fo(),l(g,69).xk()||(g=rx(ic(io,g))),o=(a=this.Ih(g),l(a>=0?this.Lh(a,!0,!0):Hw(this,g,!0),160)),E=g.Ik(),E>1||E==-1)return l(l(o,220).Sl(t,!1),79)}else throw ue(new Yn(Ob+t.xe()+$fe));else if(t.Jk())return a=this.Ih(t),l(a>=0?this.Lh(a,!1,!0):Hw(this,t,!1),79);return w=new Itt(this,t),w},h.hi=function(){return V6e(this)},h.ii=function(){return(lb(),Vn).S},h.ji=function(){return yr(this.ii())},h.ki=function(t){Fue(this,t)},h.Ib=function(){return g0(this)},I(Gn,"BasicEObjectImpl",99);var C_t;D(119,99,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1}),h.li=function(t){var n;return n=H6e(this),n[t]},h.mi=function(t,n){var r;r=H6e(this),Ts(r,t,n)},h.ni=function(t){var n;n=H6e(this),Ts(n,t,null)},h.th=function(){return l(Kn(this,4),129)},h.uh=function(){throw ue(new Qr)},h.vh=function(){return(this.Db&4)!=0},h.zh=function(){throw ue(new Qr)},h.oi=function(t){px(this,2,t)},h.Bh=function(t,n){this.Db=n<<16|this.Db&255,this.oi(t)},h.Dh=function(){return sl(this)},h.Fh=function(){return this.Db>>16},h.Gh=function(){var t,n;return w_(),n=j5e(Sd((t=l(Kn(this,16),29),t||this.ii()))),n==null?rpe:new TO(this,n)},h.wh=function(){return(this.Db&1)==0},h.Jh=function(){return l(Kn(this,128),2034)},h.Kh=function(){return l(Kn(this,16),29)},h.Oh=function(){return(this.Db&32)!=0},h.Ph=function(){return l(Kn(this,2),54)},h.Vh=function(){return(this.Db&64)!=0},h.$h=function(){throw ue(new Qr)},h._h=function(){return l(Kn(this,64),288)},h.ci=function(t){px(this,16,t)},h.di=function(t){px(this,128,t)},h.ei=function(t){px(this,64,t)},h.hi=function(){return Ku(this)},h.Db=0,I(Gn,"MinimalEObjectImpl",119),D(120,119,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),h.oi=function(t){this.Cb=t},h.Ph=function(){return this.Cb},I(Gn,"MinimalEObjectImpl/Container",120),D(2083,120,{110:1,342:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),h.Lh=function(t,n,r){return sxe(this,t,n,r)},h.Uh=function(t,n,r){return Wxe(this,t,n,r)},h.Wh=function(t){return Z5e(this,t)},h.bi=function(t,n){V7e(this,t,n)},h.ii=function(){return su(),T_t},h.ki=function(t){O7e(this,t)},h.nf=function(){return fdt(this)},h.gh=function(){return!this.o&&(this.o=new xl((su(),Cg),L2,this,0)),this.o},h.of=function(t){return at(this,t)},h.pf=function(t){return P1(this,t)},h.qf=function(t,n){return Hi(this,t,n)},I(sv,"EMapPropertyHolderImpl",2083),D(572,120,{110:1,377:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},AS),h.Lh=function(t,n,r){switch(t){case 0:return this.a;case 1:return this.b}return rU(this,t,n,r)},h.Wh=function(t){switch(t){case 0:return this.a!=0;case 1:return this.b!=0}return nue(this,t)},h.bi=function(t,n){switch(t){case 0:dV(this,ze(Ge(n)));return;case 1:fV(this,ze(Ge(n)));return}$ue(this,t,n)},h.ii=function(){return su(),y_t},h.ki=function(t){switch(t){case 0:dV(this,0);return;case 1:fV(this,0);return}Fue(this,t)},h.Ib=function(){var t;return this.Db&64?g0(this):(t=new Af(g0(this)),t.a+=" (x: ",_5(t,this.a),t.a+=", y: ",_5(t,this.b),t.a+=")",t.a)},h.a=0,h.b=0,I(sv,"ElkBendPointImpl",572),D(739,2083,{110:1,342:1,167:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),h.Lh=function(t,n,r){return d8e(this,t,n,r)},h.Sh=function(t,n,r){return Mue(this,t,n,r)},h.Uh=function(t,n,r){return dce(this,t,n,r)},h.Wh=function(t){return _7e(this,t)},h.bi=function(t,n){Txe(this,t,n)},h.ii=function(){return su(),k_t},h.ki=function(t){i8e(this,t)},h.jh=function(){return this.k},h.kh=function(){return EH(this)},h.Ib=function(){return jce(this)},h.k=null,I(sv,"ElkGraphElementImpl",739),D(740,739,{110:1,342:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),h.Lh=function(t,n,r){return x8e(this,t,n,r)},h.Wh=function(t){return _8e(this,t)},h.bi=function(t,n){Cxe(this,t,n)},h.ii=function(){return su(),E_t},h.ki=function(t){N8e(this,t)},h.lh=function(){return this.f},h.mh=function(){return this.g},h.nh=function(){return this.i},h.oh=function(){return this.j},h.ph=function(t,n){F5(this,t,n)},h.qh=function(t,n){Qh(this,t,n)},h.rh=function(t){Uu(this,t)},h.sh=function(t){Gu(this,t)},h.Ib=function(){return Pue(this)},h.f=0,h.g=0,h.i=0,h.j=0,I(sv,"ElkShapeImpl",740),D(741,740,{110:1,342:1,84:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),h.Lh=function(t,n,r){return J8e(this,t,n,r)},h.Sh=function(t,n,r){return vxe(this,t,n,r)},h.Uh=function(t,n,r){return wxe(this,t,n,r)},h.Wh=function(t){return H7e(this,t)},h.bi=function(t,n){I9e(this,t,n)},h.ii=function(){return su(),x_t},h.ki=function(t){K8e(this,t)},h.hh=function(){return!this.d&&(this.d=new Ln(js,this,8,5)),this.d},h.ih=function(){return!this.e&&(this.e=new Ln(js,this,7,4)),this.e},I(sv,"ElkConnectableShapeImpl",741),D(326,739,{110:1,342:1,74:1,167:1,326:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},TI),h.Ah=function(t){return gxe(this,t)},h.Lh=function(t,n,r){switch(t){case 3:return WO(this);case 4:return!this.b&&(this.b=new Ln(_r,this,4,7)),this.b;case 5:return!this.c&&(this.c=new Ln(_r,this,5,8)),this.c;case 6:return!this.a&&(this.a=new nt(cs,this,6,6)),this.a;case 7:return Hn(),!this.b&&(this.b=new Ln(_r,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new Ln(_r,this,5,8)),this.c.i<=1));case 8:return Hn(),!!qA(this);case 9:return Hn(),!!qw(this);case 10:return Hn(),!this.b&&(this.b=new Ln(_r,this,4,7)),this.b.i!=0&&(!this.c&&(this.c=new Ln(_r,this,5,8)),this.c.i!=0)}return d8e(this,t,n,r)},h.Sh=function(t,n,r){var a;switch(n){case 3:return this.Cb&&(r=(a=this.Db>>16,a>=0?gxe(this,r):this.Cb.Th(this,-1-a,null,r))),Yye(this,l(t,27),r);case 4:return!this.b&&(this.b=new Ln(_r,this,4,7)),Ru(this.b,t,r);case 5:return!this.c&&(this.c=new Ln(_r,this,5,8)),Ru(this.c,t,r);case 6:return!this.a&&(this.a=new nt(cs,this,6,6)),Ru(this.a,t,r)}return Mue(this,t,n,r)},h.Uh=function(t,n,r){switch(n){case 3:return Yye(this,null,r);case 4:return!this.b&&(this.b=new Ln(_r,this,4,7)),To(this.b,t,r);case 5:return!this.c&&(this.c=new Ln(_r,this,5,8)),To(this.c,t,r);case 6:return!this.a&&(this.a=new nt(cs,this,6,6)),To(this.a,t,r)}return dce(this,t,n,r)},h.Wh=function(t){switch(t){case 3:return!!WO(this);case 4:return!!this.b&&this.b.i!=0;case 5:return!!this.c&&this.c.i!=0;case 6:return!!this.a&&this.a.i!=0;case 7:return!this.b&&(this.b=new Ln(_r,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new Ln(_r,this,5,8)),this.c.i<=1));case 8:return qA(this);case 9:return qw(this);case 10:return!this.b&&(this.b=new Ln(_r,this,4,7)),this.b.i!=0&&(!this.c&&(this.c=new Ln(_r,this,5,8)),this.c.i!=0)}return _7e(this,t)},h.bi=function(t,n){switch(t){case 3:AU(this,l(n,27));return;case 4:!this.b&&(this.b=new Ln(_r,this,4,7)),$r(this.b),!this.b&&(this.b=new Ln(_r,this,4,7)),As(this.b,l(n,16));return;case 5:!this.c&&(this.c=new Ln(_r,this,5,8)),$r(this.c),!this.c&&(this.c=new Ln(_r,this,5,8)),As(this.c,l(n,16));return;case 6:!this.a&&(this.a=new nt(cs,this,6,6)),$r(this.a),!this.a&&(this.a=new nt(cs,this,6,6)),As(this.a,l(n,16));return}Txe(this,t,n)},h.ii=function(){return su(),fPe},h.ki=function(t){switch(t){case 3:AU(this,null);return;case 4:!this.b&&(this.b=new Ln(_r,this,4,7)),$r(this.b);return;case 5:!this.c&&(this.c=new Ln(_r,this,5,8)),$r(this.c);return;case 6:!this.a&&(this.a=new nt(cs,this,6,6)),$r(this.a);return}i8e(this,t)},h.Ib=function(){return evt(this)},I(sv,"ElkEdgeImpl",326),D(452,2083,{110:1,342:1,166:1,452:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},rk),h.Ah=function(t){return lxe(this,t)},h.Lh=function(t,n,r){switch(t){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return!this.a&&(this.a=new Ys(qh,this,5)),this.a;case 6:return lot(this);case 7:return n?oue(this):this.i;case 8:return n?aue(this):this.f;case 9:return!this.g&&(this.g=new Ln(cs,this,9,10)),this.g;case 10:return!this.e&&(this.e=new Ln(cs,this,10,9)),this.e;case 11:return this.d}return sxe(this,t,n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 6:return this.Cb&&(r=(o=this.Db>>16,o>=0?lxe(this,r):this.Cb.Th(this,-1-o,null,r))),Wye(this,l(t,74),r);case 9:return!this.g&&(this.g=new Ln(cs,this,9,10)),Ru(this.g,t,r);case 10:return!this.e&&(this.e=new Ln(cs,this,10,9)),Ru(this.e,t,r)}return f=l(Mn((a=l(Kn(this,16),29),a||(su(),pY)),n),69),f.wk().zk(this,Ku(this),n-yr((su(),pY)),t,r)},h.Uh=function(t,n,r){switch(n){case 5:return!this.a&&(this.a=new Ys(qh,this,5)),To(this.a,t,r);case 6:return Wye(this,null,r);case 9:return!this.g&&(this.g=new Ln(cs,this,9,10)),To(this.g,t,r);case 10:return!this.e&&(this.e=new Ln(cs,this,10,9)),To(this.e,t,r)}return Wxe(this,t,n,r)},h.Wh=function(t){switch(t){case 1:return this.j!=0;case 2:return this.k!=0;case 3:return this.b!=0;case 4:return this.c!=0;case 5:return!!this.a&&this.a.i!=0;case 6:return!!lot(this);case 7:return!!this.i;case 8:return!!this.f;case 9:return!!this.g&&this.g.i!=0;case 10:return!!this.e&&this.e.i!=0;case 11:return this.d!=null}return Z5e(this,t)},h.bi=function(t,n){switch(t){case 1:oE(this,ze(Ge(n)));return;case 2:uE(this,ze(Ge(n)));return;case 3:aE(this,ze(Ge(n)));return;case 4:cE(this,ze(Ge(n)));return;case 5:!this.a&&(this.a=new Ys(qh,this,5)),$r(this.a),!this.a&&(this.a=new Ys(qh,this,5)),As(this.a,l(n,16));return;case 6:Z2t(this,l(n,74));return;case 7:yV(this,l(n,84));return;case 8:wV(this,l(n,84));return;case 9:!this.g&&(this.g=new Ln(cs,this,9,10)),$r(this.g),!this.g&&(this.g=new Ln(cs,this,9,10)),As(this.g,l(n,16));return;case 10:!this.e&&(this.e=new Ln(cs,this,10,9)),$r(this.e),!this.e&&(this.e=new Ln(cs,this,10,9)),As(this.e,l(n,16));return;case 11:p7e(this,ei(n));return}V7e(this,t,n)},h.ii=function(){return su(),pY},h.ki=function(t){switch(t){case 1:oE(this,0);return;case 2:uE(this,0);return;case 3:aE(this,0);return;case 4:cE(this,0);return;case 5:!this.a&&(this.a=new Ys(qh,this,5)),$r(this.a);return;case 6:Z2t(this,null);return;case 7:yV(this,null);return;case 8:wV(this,null);return;case 9:!this.g&&(this.g=new Ln(cs,this,9,10)),$r(this.g);return;case 10:!this.e&&(this.e=new Ln(cs,this,10,9)),$r(this.e);return;case 11:p7e(this,null);return}O7e(this,t)},h.Ib=function(){return d2t(this)},h.b=0,h.c=0,h.d=null,h.j=0,h.k=0,I(sv,"ElkEdgeSectionImpl",452),D(158,120,{110:1,94:1,93:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1}),h.Lh=function(t,n,r){var a;return t==0?(!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab):sf(this,t-yr(this.ii()),Mn((a=l(Kn(this,16),29),a||this.ii()),t),n,r)},h.Sh=function(t,n,r){var a,o;return n==0?(!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r)):(o=l(Mn((a=l(Kn(this,16),29),a||this.ii()),n),69),o.wk().zk(this,Ku(this),n-yr(this.ii()),t,r))},h.Uh=function(t,n,r){var a,o;return n==0?(!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r)):(o=l(Mn((a=l(Kn(this,16),29),a||this.ii()),n),69),o.wk().Ak(this,Ku(this),n-yr(this.ii()),t,r))},h.Wh=function(t){var n;return t==0?!!this.Ab&&this.Ab.i!=0:nf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.Zh=function(t){return Hke(this,t)},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return}uf(this,t-yr(this.ii()),Mn((r=l(Kn(this,16),29),r||this.ii()),t),n)},h.di=function(t){px(this,128,t)},h.ii=function(){return Tn(),H_t},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return}cf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.pi=function(){this.Bb|=1},h.qi=function(t){return YA(this,t)},h.Bb=0,I(Gn,"EModelElementImpl",158),D(720,158,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},fz),h.ri=function(t,n){return Lvt(this,t,n)},h.si=function(t){var n,r,a,o,f;if(this.a!=Ah(t)||t.Bb&256)throw ue(new Yn(qfe+t.zb+t3));for(a=dc(t);du(a.a).i!=0;){if(r=l(mP(a,0,(n=l(Oe(du(a.a),0),89),f=n.c,De(f,90)?l(f,29):(Tn(),Kf))),29),zw(r))return o=Ah(r).wi().si(r),l(o,54).ci(t),o;a=dc(r)}return(t.D!=null?t.D:t.B)=="java.util.Map$Entry"?new Git(t):new F4e(t)},h.ti=function(t,n){return Kw(this,t,n)},h.Lh=function(t,n,r){var a;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.a}return sf(this,t-yr((Tn(),em)),Mn((a=l(Kn(this,16),29),a||em),t),n,r)},h.Sh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 1:return this.a&&(r=l(this.a,54).Th(this,4,u1,r)),r8e(this,l(t,241),r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),em)),n),69),o.wk().zk(this,Ku(this),n-yr((Tn(),em)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 1:return r8e(this,null,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),em)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),em)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return!!this.a}return nf(this,t-yr((Tn(),em)),Mn((n=l(Kn(this,16),29),n||em),t))},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:Xgt(this,l(n,241));return}uf(this,t-yr((Tn(),em)),Mn((r=l(Kn(this,16),29),r||em),t),n)},h.ii=function(){return Tn(),em},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:Xgt(this,null);return}cf(this,t-yr((Tn(),em)),Mn((n=l(Kn(this,16),29),n||em),t))};var jM,bPe,S_t;I(Gn,"EFactoryImpl",720),D(1037,720,{110:1,2113:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},ik),h.ri=function(t,n){switch(t.hk()){case 12:return l(n,149).Pg();case 13:return xc(n);default:throw ue(new Yn(yT+t.xe()+t3))}},h.si=function(t){var n,r,a,o,f,g,w,E;switch(t.G==-1&&(t.G=(n=Ah(t),n?f2(n.vi(),t):-1)),t.G){case 4:return f=new sk,f;case 6:return g=new a_,g;case 7:return w=new jwe,w;case 8:return a=new TI,a;case 9:return r=new AS,r;case 10:return o=new rk,o;case 11:return E=new k$,E;default:throw ue(new Yn(qfe+t.zb+t3))}},h.ti=function(t,n){switch(t.hk()){case 13:case 12:return null;default:throw ue(new Yn(yT+t.xe()+t3))}},I(sv,"ElkGraphFactoryImpl",1037),D(448,158,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1}),h.Gh=function(){var t,n;return n=(t=l(Kn(this,16),29),j5e(Sd(t||this.ii()))),n==null?(w_(),w_(),rpe):new prt(this,n)},h.Lh=function(t,n,r){var a;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.xe()}return sf(this,t-yr(this.ii()),Mn((a=l(Kn(this,16),29),a||this.ii()),t),n,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null}return nf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:this.ui(ei(n));return}uf(this,t-yr(this.ii()),Mn((r=l(Kn(this,16),29),r||this.ii()),t),n)},h.ii=function(){return Tn(),V_t},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:this.ui(null);return}cf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.xe=function(){return this.zb},h.ui=function(t){Fu(this,t)},h.Ib=function(){return CA(this)},h.zb=null,I(Gn,"ENamedElementImpl",448),D(184,448,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},qat),h.Ah=function(t){return ogt(this,t)},h.Lh=function(t,n,r){var a;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return!this.rb&&(this.rb=new wy(this,l1,this)),this.rb;case 6:return!this.vb&&(this.vb=new V8(u1,this,6,7)),this.vb;case 7:return n?this.Db>>16==7?l(this.Cb,241):null:mot(this)}return sf(this,t-yr((Tn(),O2)),Mn((a=l(Kn(this,16),29),a||O2),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 4:return this.sb&&(r=l(this.sb,54).Th(this,1,RM,r)),a8e(this,l(t,480),r);case 5:return!this.rb&&(this.rb=new wy(this,l1,this)),Ru(this.rb,t,r);case 6:return!this.vb&&(this.vb=new V8(u1,this,6,7)),Ru(this.vb,t,r);case 7:return this.Cb&&(r=(o=this.Db>>16,o>=0?ogt(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,7,r)}return f=l(Mn((a=l(Kn(this,16),29),a||(Tn(),O2)),n),69),f.wk().zk(this,Ku(this),n-yr((Tn(),O2)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 4:return a8e(this,null,r);case 5:return!this.rb&&(this.rb=new wy(this,l1,this)),To(this.rb,t,r);case 6:return!this.vb&&(this.vb=new V8(u1,this,6,7)),To(this.vb,t,r);case 7:return Nh(this,null,7,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),O2)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),O2)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.yb!=null;case 3:return this.xb!=null;case 4:return!!this.sb;case 5:return!!this.rb&&this.rb.i!=0;case 6:return!!this.vb&&this.vb.i!=0;case 7:return!!mot(this)}return nf(this,t-yr((Tn(),O2)),Mn((n=l(Kn(this,16),29),n||O2),t))},h.Zh=function(t){var n;return n=wCn(this,t),n||Hke(this,t)},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:Fu(this,ei(n));return;case 2:SV(this,ei(n));return;case 3:CV(this,ei(n));return;case 4:Nue(this,l(n,480));return;case 5:!this.rb&&(this.rb=new wy(this,l1,this)),$r(this.rb),!this.rb&&(this.rb=new wy(this,l1,this)),As(this.rb,l(n,16));return;case 6:!this.vb&&(this.vb=new V8(u1,this,6,7)),$r(this.vb),!this.vb&&(this.vb=new V8(u1,this,6,7)),As(this.vb,l(n,16));return}uf(this,t-yr((Tn(),O2)),Mn((r=l(Kn(this,16),29),r||O2),t),n)},h.ei=function(t){var n,r;if(t&&this.rb)for(r=new or(this.rb);r.e!=r.i.gc();)n=gr(r),De(n,364)&&(l(n,364).w=null);px(this,64,t)},h.ii=function(){return Tn(),O2},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:Fu(this,null);return;case 2:SV(this,null);return;case 3:CV(this,null);return;case 4:Nue(this,null);return;case 5:!this.rb&&(this.rb=new wy(this,l1,this)),$r(this.rb);return;case 6:!this.vb&&(this.vb=new V8(u1,this,6,7)),$r(this.vb);return}cf(this,t-yr((Tn(),O2)),Mn((n=l(Kn(this,16),29),n||O2),t))},h.pi=function(){yue(this)},h.vi=function(){return!this.rb&&(this.rb=new wy(this,l1,this)),this.rb},h.wi=function(){return this.sb},h.xi=function(){return this.ub},h.yi=function(){return this.xb},h.zi=function(){return this.yb},h.Ai=function(t){this.ub=t},h.Ib=function(){var t;return this.Db&64?CA(this):(t=new Af(CA(this)),t.a+=" (nsURI: ",Xo(t,this.yb),t.a+=", nsPrefix: ",Xo(t,this.xb),t.a+=")",t.a)},h.xb=null,h.yb=null,I(Gn,"EPackageImpl",184),D(569,184,{110:1,2115:1,569:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},k2t),h.q=!1,h.r=!1;var __t=!1;I(sv,"ElkGraphPackageImpl",569),D(366,740,{110:1,342:1,167:1,135:1,422:1,366:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},sk),h.Ah=function(t){return hxe(this,t)},h.Lh=function(t,n,r){switch(t){case 7:return vot(this);case 8:return this.a}return x8e(this,t,n,r)},h.Sh=function(t,n,r){var a;switch(n){case 7:return this.Cb&&(r=(a=this.Db>>16,a>=0?hxe(this,r):this.Cb.Th(this,-1-a,null,r))),J4e(this,l(t,167),r)}return Mue(this,t,n,r)},h.Uh=function(t,n,r){return n==7?J4e(this,null,r):dce(this,t,n,r)},h.Wh=function(t){switch(t){case 7:return!!vot(this);case 8:return!vn("",this.a)}return _8e(this,t)},h.bi=function(t,n){switch(t){case 7:U9e(this,l(n,167));return;case 8:l7e(this,ei(n));return}Cxe(this,t,n)},h.ii=function(){return su(),dPe},h.ki=function(t){switch(t){case 7:U9e(this,null);return;case 8:l7e(this,"");return}N8e(this,t)},h.Ib=function(){return lpt(this)},h.a="",I(sv,"ElkLabelImpl",366),D(207,741,{110:1,342:1,84:1,167:1,27:1,422:1,207:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},a_),h.Ah=function(t){return pxe(this,t)},h.Lh=function(t,n,r){switch(t){case 9:return!this.c&&(this.c=new nt(Hl,this,9,9)),this.c;case 10:return!this.a&&(this.a=new nt(Ai,this,10,11)),this.a;case 11:return ds(this);case 12:return!this.b&&(this.b=new nt(js,this,12,3)),this.b;case 13:return Hn(),!this.a&&(this.a=new nt(Ai,this,10,11)),this.a.i>0}return J8e(this,t,n,r)},h.Sh=function(t,n,r){var a;switch(n){case 9:return!this.c&&(this.c=new nt(Hl,this,9,9)),Ru(this.c,t,r);case 10:return!this.a&&(this.a=new nt(Ai,this,10,11)),Ru(this.a,t,r);case 11:return this.Cb&&(r=(a=this.Db>>16,a>=0?pxe(this,r):this.Cb.Th(this,-1-a,null,r))),s4e(this,l(t,27),r);case 12:return!this.b&&(this.b=new nt(js,this,12,3)),Ru(this.b,t,r)}return vxe(this,t,n,r)},h.Uh=function(t,n,r){switch(n){case 9:return!this.c&&(this.c=new nt(Hl,this,9,9)),To(this.c,t,r);case 10:return!this.a&&(this.a=new nt(Ai,this,10,11)),To(this.a,t,r);case 11:return s4e(this,null,r);case 12:return!this.b&&(this.b=new nt(js,this,12,3)),To(this.b,t,r)}return wxe(this,t,n,r)},h.Wh=function(t){switch(t){case 9:return!!this.c&&this.c.i!=0;case 10:return!!this.a&&this.a.i!=0;case 11:return!!ds(this);case 12:return!!this.b&&this.b.i!=0;case 13:return!this.a&&(this.a=new nt(Ai,this,10,11)),this.a.i>0}return H7e(this,t)},h.bi=function(t,n){switch(t){case 9:!this.c&&(this.c=new nt(Hl,this,9,9)),$r(this.c),!this.c&&(this.c=new nt(Hl,this,9,9)),As(this.c,l(n,16));return;case 10:!this.a&&(this.a=new nt(Ai,this,10,11)),$r(this.a),!this.a&&(this.a=new nt(Ai,this,10,11)),As(this.a,l(n,16));return;case 11:LU(this,l(n,27));return;case 12:!this.b&&(this.b=new nt(js,this,12,3)),$r(this.b),!this.b&&(this.b=new nt(js,this,12,3)),As(this.b,l(n,16));return}I9e(this,t,n)},h.ii=function(){return su(),gPe},h.ki=function(t){switch(t){case 9:!this.c&&(this.c=new nt(Hl,this,9,9)),$r(this.c);return;case 10:!this.a&&(this.a=new nt(Ai,this,10,11)),$r(this.a);return;case 11:LU(this,null);return;case 12:!this.b&&(this.b=new nt(js,this,12,3)),$r(this.b);return}K8e(this,t)},h.Ib=function(){return oke(this)},I(sv,"ElkNodeImpl",207),D(193,741,{110:1,342:1,84:1,167:1,123:1,422:1,193:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},jwe),h.Ah=function(t){return fxe(this,t)},h.Lh=function(t,n,r){return t==9?M1(this):J8e(this,t,n,r)},h.Sh=function(t,n,r){var a;switch(n){case 9:return this.Cb&&(r=(a=this.Db>>16,a>=0?fxe(this,r):this.Cb.Th(this,-1-a,null,r))),Xye(this,l(t,27),r)}return vxe(this,t,n,r)},h.Uh=function(t,n,r){return n==9?Xye(this,null,r):wxe(this,t,n,r)},h.Wh=function(t){return t==9?!!M1(this):H7e(this,t)},h.bi=function(t,n){switch(t){case 9:z9e(this,l(n,27));return}I9e(this,t,n)},h.ii=function(){return su(),pPe},h.ki=function(t){switch(t){case 9:z9e(this,null);return}K8e(this,t)},h.Ib=function(){return Jbt(this)},I(sv,"ElkPortImpl",193);var A_t=ks(So,"BasicEMap/Entry");D(1122,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,119:1,120:1},k$),h.Fb=function(t){return this===t},h.ld=function(){return this.b},h.Hb=function(){return fw(this)},h.Di=function(t){h7e(this,l(t,149))},h.Lh=function(t,n,r){switch(t){case 0:return this.b;case 1:return this.c}return rU(this,t,n,r)},h.Wh=function(t){switch(t){case 0:return!!this.b;case 1:return this.c!=null}return nue(this,t)},h.bi=function(t,n){switch(t){case 0:h7e(this,l(n,149));return;case 1:u7e(this,n);return}$ue(this,t,n)},h.ii=function(){return su(),Cg},h.ki=function(t){switch(t){case 0:h7e(this,null);return;case 1:u7e(this,null);return}Fue(this,t)},h.Bi=function(){var t;return this.a==-1&&(t=this.b,this.a=t?es(t):0),this.a},h.md=function(){return this.c},h.Ci=function(t){this.a=t},h.nd=function(t){var n;return n=this.c,u7e(this,t),n},h.Ib=function(){var t;return this.Db&64?g0(this):(t=new tb,hi(hi(hi(t,this.b?this.b.Pg():ul),Phe),j_(this.c)),t.a)},h.a=-1,h.c=null;var L2=I(sv,"ElkPropertyToValueMapEntryImpl",1122);D(996,1,{},T$),I(no,"JsonAdapter",996),D(216,63,lp,dd),I(no,"JsonImportException",216),D(868,1,{},cgt),I(no,"JsonImporter",868),D(903,1,{},ptt),I(no,"JsonImporter/lambda$0$Type",903),D(904,1,{},btt),I(no,"JsonImporter/lambda$1$Type",904),D(912,1,{},FXe),I(no,"JsonImporter/lambda$10$Type",912),D(914,1,{},mtt),I(no,"JsonImporter/lambda$11$Type",914),D(915,1,{},vtt),I(no,"JsonImporter/lambda$12$Type",915),D(921,1,{},Mat),I(no,"JsonImporter/lambda$13$Type",921),D(920,1,{},Dat),I(no,"JsonImporter/lambda$14$Type",920),D(916,1,{},wtt),I(no,"JsonImporter/lambda$15$Type",916),D(917,1,{},ytt),I(no,"JsonImporter/lambda$16$Type",917),D(918,1,{},xtt),I(no,"JsonImporter/lambda$17$Type",918),D(919,1,{},ktt),I(no,"JsonImporter/lambda$18$Type",919),D(924,1,{},RXe),I(no,"JsonImporter/lambda$19$Type",924),D(905,1,{},jXe),I(no,"JsonImporter/lambda$2$Type",905),D(922,1,{},$Xe),I(no,"JsonImporter/lambda$20$Type",922),D(923,1,{},zXe),I(no,"JsonImporter/lambda$21$Type",923),D(927,1,{},qXe),I(no,"JsonImporter/lambda$22$Type",927),D(925,1,{},HXe),I(no,"JsonImporter/lambda$23$Type",925),D(926,1,{},VXe),I(no,"JsonImporter/lambda$24$Type",926),D(929,1,{},UXe),I(no,"JsonImporter/lambda$25$Type",929),D(928,1,{},GXe),I(no,"JsonImporter/lambda$26$Type",928),D(930,1,fr,Ett),h.Cd=function(t){Ovn(this.b,this.a,ei(t))},I(no,"JsonImporter/lambda$27$Type",930),D(931,1,fr,Ttt),h.Cd=function(t){Nvn(this.b,this.a,ei(t))},I(no,"JsonImporter/lambda$28$Type",931),D(932,1,{},Ctt),I(no,"JsonImporter/lambda$29$Type",932),D(908,1,{},KXe),I(no,"JsonImporter/lambda$3$Type",908),D(933,1,{},Stt),I(no,"JsonImporter/lambda$30$Type",933),D(934,1,{},WXe),I(no,"JsonImporter/lambda$31$Type",934),D(935,1,{},YXe),I(no,"JsonImporter/lambda$32$Type",935),D(936,1,{},XXe),I(no,"JsonImporter/lambda$33$Type",936),D(937,1,{},QXe),I(no,"JsonImporter/lambda$34$Type",937),D(870,1,{},JXe),I(no,"JsonImporter/lambda$35$Type",870),D(941,1,{},yit),I(no,"JsonImporter/lambda$36$Type",941),D(938,1,fr,ZXe),h.Cd=function(t){jmn(this.a,l(t,377))},I(no,"JsonImporter/lambda$37$Type",938),D(939,1,fr,_tt),h.Cd=function(t){yln(this.a,this.b,l(t,166))},I(no,"JsonImporter/lambda$38$Type",939),D(940,1,fr,Att),h.Cd=function(t){xln(this.a,this.b,l(t,166))},I(no,"JsonImporter/lambda$39$Type",940),D(906,1,{},eQe),I(no,"JsonImporter/lambda$4$Type",906),D(942,1,fr,tQe),h.Cd=function(t){$mn(this.a,l(t,8))},I(no,"JsonImporter/lambda$40$Type",942),D(907,1,{},nQe),I(no,"JsonImporter/lambda$5$Type",907),D(911,1,{},rQe),I(no,"JsonImporter/lambda$6$Type",911),D(909,1,{},iQe),I(no,"JsonImporter/lambda$7$Type",909),D(910,1,{},sQe),I(no,"JsonImporter/lambda$8$Type",910),D(913,1,{},aQe),I(no,"JsonImporter/lambda$9$Type",913),D(961,1,fr,oQe),h.Cd=function(t){J8(this.a,new yy(ei(t)))},I(no,"JsonMetaDataConverter/lambda$0$Type",961),D(962,1,fr,cQe),h.Cd=function(t){Dgn(this.a,l(t,245))},I(no,"JsonMetaDataConverter/lambda$1$Type",962),D(963,1,fr,uQe),h.Cd=function(t){M2n(this.a,l(t,143))},I(no,"JsonMetaDataConverter/lambda$2$Type",963),D(964,1,fr,lQe),h.Cd=function(t){Ign(this.a,l(t,170))},I(no,"JsonMetaDataConverter/lambda$3$Type",964),D(245,22,{3:1,34:1,22:1,245:1},R8);var bY,mY,Xge,vY,wY,yY,Qge,Jge,xY=Fr(IP,"GraphFeature",245,Hr,pwn,idn),L_t;D(11,1,{34:1,149:1},Ui,vs,pn,Ha),h.Fd=function(t){return Shn(this,l(t,149))},h.Fb=function(t){return eot(this,t)},h.Sg=function(){return It(this)},h.Pg=function(){return this.b},h.Hb=function(){return s2(this.b)},h.Ib=function(){return this.b},I(IP,"Property",11),D(671,1,ii,Nie),h.Ne=function(t,n){return B4n(this,l(t,96),l(n,96))},h.Fb=function(t){return this===t},h.Oe=function(){return new Vt(this)},I(IP,"PropertyHolderComparator",671),D(709,1,Oa,ywe),h.Nb=function(t){Za(this,t)},h.Pb=function(){return Fvn(this)},h.Qb=function(){aZe()},h.Ob=function(){return!!this.a},I(qG,"ElkGraphUtil/AncestorIterator",709);var mPe=ks(So,"EList");D(70,56,{20:1,31:1,56:1,16:1,15:1,70:1,61:1}),h.bd=function(t,n){_A(this,t,n)},h.Fc=function(t){return qr(this,t)},h.cd=function(t,n){return N7e(this,t,n)},h.Gc=function(t){return As(this,t)},h.Ii=function(){return new H8(this)},h.Ji=function(){return new CO(this)},h.Ki=function(t){return mN(this,t)},h.Li=function(){return!0},h.Mi=function(t,n){},h.Ni=function(){},h.Oi=function(t,n){Noe(this,t,n)},h.Pi=function(t,n,r){},h.Qi=function(t,n){},h.Ri=function(t,n,r){},h.Fb=function(t){return Bbt(this,t)},h.Hb=function(){return M7e(this)},h.Si=function(){return!1},h.Kc=function(){return new or(this)},h.ed=function(){return new q8(this)},h.fd=function(t){var n;if(n=this.gc(),t<0||t>n)throw ue(new my(t,n));return new jae(this,t)},h.Ui=function(t,n){this.Ti(t,this.dd(n))},h.Mc=function(t){return sV(this,t)},h.Wi=function(t,n){return n},h.hd=function(t,n){return n6(this,t,n)},h.Ib=function(){return T8e(this)},h.Yi=function(){return!0},h.Zi=function(t,n){return EE(this,n)},I(So,"AbstractEList",70),D(66,70,Bd,X2,Lw,T7e),h.Ei=function(t,n){return Due(this,t,n)},h.Fi=function(t){return Odt(this,t)},h.Gi=function(t,n){IN(this,t,n)},h.Hi=function(t){tN(this,t)},h.$i=function(t){return R6e(this,t)},h.$b=function(){uA(this)},h.Hc=function(t){return jE(this,t)},h.Xb=function(t){return Oe(this,t)},h._i=function(t){var n,r,a;++this.j,r=this.g==null?0:this.g.length,t>r&&(a=this.g,n=r+(r/2|0)+4,n=0?(this.gd(n),!0):!1},h.Xi=function(t,n){return this.Dj(t,this.Zi(t,n))},h.gc=function(){return this.Ej()},h.Pc=function(){return this.Fj()},h.Qc=function(t){return this.Gj(t)},h.Ib=function(){return this.Hj()},I(So,"DelegatingEList",2093),D(2094,2093,J4t),h.Ei=function(t,n){return wke(this,t,n)},h.Fi=function(t){return this.Ei(this.Ej(),t)},h.Gi=function(t,n){E2t(this,t,n)},h.Hi=function(t){h2t(this,t)},h.Li=function(){return!this.Mj()},h.$b=function(){tL(this)},h.Ij=function(t,n,r,a,o){return new Zat(this,t,n,r,a,o)},h.Jj=function(t){Ni(this.jj(),t)},h.Kj=function(){return null},h.Lj=function(){return-1},h.jj=function(){return null},h.Mj=function(){return!1},h.Nj=function(t,n){return n},h.Oj=function(t,n){return n},h.Pj=function(){return!1},h.Qj=function(){return!this.Aj()},h.Ti=function(t,n){var r,a;return this.Pj()?(a=this.Qj(),r=Uxe(this,t,n),this.Jj(this.Ij(7,pt(n),r,t,a)),r):Uxe(this,t,n)},h.gd=function(t){var n,r,a,o;return this.Pj()?(r=null,a=this.Qj(),n=this.Ij(4,o=rH(this,t),null,t,a),this.Mj()&&o?(r=this.Oj(o,r),r?(r.nj(n),r.oj()):this.Jj(n)):r?(r.nj(n),r.oj()):this.Jj(n),o):(o=rH(this,t),this.Mj()&&o&&(r=this.Oj(o,null),r&&r.oj()),o)},h.Xi=function(t,n){return Mmt(this,t,n)},I(Rx,"DelegatingNotifyingListImpl",2094),D(152,1,YP),h.nj=function(t){return Mxe(this,t)},h.oj=function(){qoe(this)},h.gj=function(){return this.d},h.Kj=function(){return null},h.Rj=function(){return null},h.hj=function(t){return-1},h.ij=function(){return mbt(this)},h.jj=function(){return null},h.kj=function(){return X9e(this)},h.lj=function(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o},h.Sj=function(){return!1},h.mj=function(t){var n,r,a,o,f,g,w,E,C,L,B;switch(this.d){case 1:case 2:switch(o=t.gj(),o){case 1:case 2:if(f=t.jj(),qe(f)===qe(this.jj())&&this.hj(null)==t.hj(null))return this.g=t.ij(),t.gj()==1&&(this.d=1),!0}case 4:{switch(o=t.gj(),o){case 4:{if(f=t.jj(),qe(f)===qe(this.jj())&&this.hj(null)==t.hj(null))return C=Bke(this),E=this.o<0?this.o<-2?-2-this.o-1:-1:this.o,g=t.lj(),this.d=6,B=new Lw(2),E<=g?(qr(B,this.n),qr(B,t.kj()),this.g=he(le(Vr,1),di,28,15,[this.o=E,g+1])):(qr(B,t.kj()),qr(B,this.n),this.g=he(le(Vr,1),di,28,15,[this.o=g,E])),this.n=B,C||(this.o=-2-this.o-1),!0;break}}break}case 6:{switch(o=t.gj(),o){case 4:{if(f=t.jj(),qe(f)===qe(this.jj())&&this.hj(null)==t.hj(null)){for(C=Bke(this),g=t.lj(),L=l(this.g,53),a=We(Vr,di,28,L.length+1,15,1),n=0;n>>0,n.toString(16))),a.a+=" (eventType: ",this.d){case 1:{a.a+="SET";break}case 2:{a.a+="UNSET";break}case 3:{a.a+="ADD";break}case 5:{a.a+="ADD_MANY";break}case 4:{a.a+="REMOVE";break}case 6:{a.a+="REMOVE_MANY";break}case 7:{a.a+="MOVE";break}case 8:{a.a+="REMOVING_ADAPTER";break}case 9:{a.a+="RESOLVE";break}default:{ise(a,this.d);break}}if(imt(this)&&(a.a+=", touch: true"),a.a+=", position: ",ise(a,this.o<0?this.o<-2?-2-this.o-1:-1:this.o),a.a+=", notifier: ",O_(a,this.jj()),a.a+=", feature: ",O_(a,this.Kj()),a.a+=", oldValue: ",O_(a,X9e(this)),a.a+=", newValue: ",this.d==6&&De(this.g,53)){for(r=l(this.g,53),a.a+="[",t=0;t10?((!this.b||this.c.j!=this.a)&&(this.b=new U_(this),this.a=this.j),W0(this.b,t)):jE(this,t)},h.Yi=function(){return!0},h.a=0,I(So,"AbstractEList/1",966),D(302,77,she,my),I(So,"AbstractEList/BasicIndexOutOfBoundsException",302),D(37,1,Oa,or),h.Nb=function(t){Za(this,t)},h.Xj=function(){if(this.i.j!=this.f)throw ue(new Xh)},h.Yj=function(){return gr(this)},h.Ob=function(){return this.e!=this.i.gc()},h.Pb=function(){return this.Yj()},h.Qb=function(){jA(this)},h.e=0,h.f=0,h.g=-1,I(So,"AbstractEList/EIterator",37),D(286,37,lg,q8,jae),h.Qb=function(){jA(this)},h.Rb=function(t){D1t(this,t)},h.Zj=function(){var t;try{return t=this.d.Xb(--this.e),this.Xj(),this.g=this.e,t}catch(n){throw n=bs(n),De(n,77)?(this.Xj(),ue(new _c)):ue(n)}},h.$j=function(t){Bdt(this,t)},h.Sb=function(){return this.e!=0},h.Tb=function(){return this.e},h.Ub=function(){return this.Zj()},h.Vb=function(){return this.e-1},h.Wb=function(t){this.$j(t)},I(So,"AbstractEList/EListIterator",286),D(355,37,Oa,H8),h.Yj=function(){return rue(this)},h.Qb=function(){throw ue(new Qr)},I(So,"AbstractEList/NonResolvingEIterator",355),D(398,286,lg,CO,f4e),h.Rb=function(t){throw ue(new Qr)},h.Yj=function(){var t;try{return t=this.c.Vi(this.e),this.Xj(),this.g=this.e++,t}catch(n){throw n=bs(n),De(n,77)?(this.Xj(),ue(new _c)):ue(n)}},h.Zj=function(){var t;try{return t=this.c.Vi(--this.e),this.Xj(),this.g=this.e,t}catch(n){throw n=bs(n),De(n,77)?(this.Xj(),ue(new _c)):ue(n)}},h.Qb=function(){throw ue(new Qr)},h.Wb=function(t){throw ue(new Qr)},I(So,"AbstractEList/NonResolvingEListIterator",398),D(2080,70,Z4t),h.Ei=function(t,n){var r,a,o,f,g,w,E,C,L,B,z;if(o=n.gc(),o!=0){for(C=l(Kn(this.a,4),129),L=C==null?0:C.length,z=L+o,a=Sce(this,z),B=L-t,B>0&&pu(C,t,a,t+o,B),E=n.Kc(),g=0;gr)throw ue(new my(t,r));return new xat(this,t)},h.$b=function(){var t,n;++this.j,t=l(Kn(this.a,4),129),n=t==null?0:t.length,PE(this,null),Noe(this,n,t)},h.Hc=function(t){var n,r,a,o,f;if(n=l(Kn(this.a,4),129),n!=null){if(t!=null){for(a=n,o=0,f=a.length;o=r)throw ue(new my(t,r));return n[t]},h.dd=function(t){var n,r,a;if(n=l(Kn(this.a,4),129),n!=null){if(t!=null){for(r=0,a=n.length;rr)throw ue(new my(t,r));return new yat(this,t)},h.Ti=function(t,n){var r,a,o;if(r=z1t(this),o=r==null?0:r.length,t>=o)throw ue(new tc(Qfe+t+av+o));if(n>=o)throw ue(new tc(Jfe+n+av+o));return a=r[n],t!=n&&(t0&&pu(t,0,n,0,r),n},h.Qc=function(t){var n,r,a;return n=l(Kn(this.a,4),129),a=n==null?0:n.length,a>0&&(t.lengtha&&Ts(t,a,null),t};var M_t;I(So,"ArrayDelegatingEList",2080),D(1051,37,Oa,kut),h.Xj=function(){if(this.b.j!=this.f||qe(l(Kn(this.b.a,4),129))!==qe(this.a))throw ue(new Xh)},h.Qb=function(){jA(this),this.a=l(Kn(this.b.a,4),129)},I(So,"ArrayDelegatingEList/EIterator",1051),D(722,286,lg,Nst,yat),h.Xj=function(){if(this.b.j!=this.f||qe(l(Kn(this.b.a,4),129))!==qe(this.a))throw ue(new Xh)},h.$j=function(t){Bdt(this,t),this.a=l(Kn(this.b.a,4),129)},h.Qb=function(){jA(this),this.a=l(Kn(this.b.a,4),129)},I(So,"ArrayDelegatingEList/EListIterator",722),D(1052,355,Oa,Eut),h.Xj=function(){if(this.b.j!=this.f||qe(l(Kn(this.b.a,4),129))!==qe(this.a))throw ue(new Xh)},I(So,"ArrayDelegatingEList/NonResolvingEIterator",1052),D(723,398,lg,Pst,xat),h.Xj=function(){if(this.b.j!=this.f||qe(l(Kn(this.b.a,4),129))!==qe(this.a))throw ue(new Xh)},I(So,"ArrayDelegatingEList/NonResolvingEListIterator",723),D(615,302,she,Vse),I(So,"BasicEList/BasicIndexOutOfBoundsException",615),D(710,66,Bd,eye),h.bd=function(t,n){throw ue(new Qr)},h.Fc=function(t){throw ue(new Qr)},h.cd=function(t,n){throw ue(new Qr)},h.Gc=function(t){throw ue(new Qr)},h.$b=function(){throw ue(new Qr)},h._i=function(t){throw ue(new Qr)},h.Kc=function(){return this.Ii()},h.ed=function(){return this.Ji()},h.fd=function(t){return this.Ki(t)},h.Ti=function(t,n){throw ue(new Qr)},h.Ui=function(t,n){throw ue(new Qr)},h.gd=function(t){throw ue(new Qr)},h.Mc=function(t){throw ue(new Qr)},h.hd=function(t,n){throw ue(new Qr)},I(So,"BasicEList/UnmodifiableEList",710),D(721,1,{3:1,20:1,16:1,15:1,61:1,597:1}),h.bd=function(t,n){ghn(this,t,l(n,44))},h.Fc=function(t){return ofn(this,l(t,44))},h.Jc=function(t){to(this,t)},h.Xb=function(t){return l(Oe(this.c,t),136)},h.Ti=function(t,n){return l(this.c.Ti(t,n),44)},h.Ui=function(t,n){phn(this,t,l(n,44))},h.Lc=function(){return new bn(null,new kn(this,16))},h.gd=function(t){return l(this.c.gd(t),44)},h.hd=function(t,n){return Mgn(this,t,l(n,44))},h.jd=function(t){$m(this,t)},h.Nc=function(){return new kn(this,16)},h.Oc=function(){return new bn(null,new kn(this,16))},h.cd=function(t,n){return this.c.cd(t,n)},h.Gc=function(t){return this.c.Gc(t)},h.$b=function(){this.c.$b()},h.Hc=function(t){return this.c.Hc(t)},h.Ic=function(t){return EN(this.c,t)},h._j=function(){var t,n,r;if(this.d==null){for(this.d=We(vPe,_Se,66,2*this.f+1,0,1),r=this.e,this.f=0,n=this.c.Kc();n.e!=n.i.gc();)t=l(n.Yj(),136),oU(this,t);this.e=r}},h.Fb=function(t){return cit(this,t)},h.Hb=function(){return M7e(this.c)},h.dd=function(t){return this.c.dd(t)},h.ak=function(){this.c=new hQe(this)},h.dc=function(){return this.f==0},h.Kc=function(){return this.c.Kc()},h.ed=function(){return this.c.ed()},h.fd=function(t){return this.c.fd(t)},h.bk=function(){return iN(this)},h.ck=function(t,n,r){return new xit(t,n,r)},h.dk=function(){return new S$},h.Mc=function(t){return Wht(this,t)},h.gc=function(){return this.f},h.kd=function(t,n){return new Zp(this.c,t,n)},h.Pc=function(){return this.c.Pc()},h.Qc=function(t){return this.c.Qc(t)},h.Ib=function(){return T8e(this.c)},h.e=0,h.f=0,I(So,"BasicEMap",721),D(1046,66,Bd,hQe),h.Mi=function(t,n){Gcn(this,l(n,136))},h.Pi=function(t,n,r){var a;++(a=this,l(n,136),a).a.e},h.Qi=function(t,n){Kcn(this,l(n,136))},h.Ri=function(t,n,r){Ghn(this,l(n,136),l(r,136))},h.Oi=function(t,n){zft(this.a)},I(So,"BasicEMap/1",1046),D(1047,66,Bd,S$),h.aj=function(t){return We(NOn,e5t,621,t,0,1)},I(So,"BasicEMap/2",1047),D(1048,q1,Tl,fQe),h.$b=function(){this.a.c.$b()},h.Hc=function(t){return Kce(this.a,t)},h.Kc=function(){return this.a.f==0?(Fk(),fF.a):new WJe(this.a)},h.Mc=function(t){var n;return n=this.a.f,YV(this.a,t),this.a.f!=n},h.gc=function(){return this.a.f},I(So,"BasicEMap/3",1048),D(1049,31,Wy,dQe),h.$b=function(){this.a.c.$b()},h.Hc=function(t){return Fbt(this.a,t)},h.Kc=function(){return this.a.f==0?(Fk(),fF.a):new YJe(this.a)},h.gc=function(){return this.a.f},I(So,"BasicEMap/4",1049),D(1050,q1,Tl,gQe),h.$b=function(){this.a.c.$b()},h.Hc=function(t){var n,r,a,o,f,g,w,E,C;if(this.a.f>0&&De(t,44)&&(this.a._j(),E=l(t,44),w=E.ld(),o=w==null?0:es(w),f=Qye(this.a,o),n=this.a.d[f],n)){for(r=l(n.g,379),C=n.i,g=0;g"+this.c},h.a=0;var NOn=I(So,"BasicEMap/EntryImpl",621);D(546,1,{},MS),I(So,"BasicEMap/View",546);var fF;D(783,1,{}),h.Fb=function(t){return O9e((Cn(),_o),t)},h.Hb=function(){return q7e((Cn(),_o))},h.Ib=function(){return Tb((Cn(),_o))},I(So,"ECollections/BasicEmptyUnmodifiableEList",783),D(1348,1,lg,Qne),h.Nb=function(t){Za(this,t)},h.Rb=function(t){throw ue(new Qr)},h.Ob=function(){return!1},h.Sb=function(){return!1},h.Pb=function(){throw ue(new _c)},h.Tb=function(){return 0},h.Ub=function(){throw ue(new _c)},h.Vb=function(){return-1},h.Qb=function(){throw ue(new Qr)},h.Wb=function(t){throw ue(new Qr)},I(So,"ECollections/BasicEmptyUnmodifiableEList/1",1348),D(1346,783,{20:1,16:1,15:1,61:1},iJe),h.bd=function(t,n){wZe()},h.Fc=function(t){return yZe()},h.cd=function(t,n){return xZe()},h.Gc=function(t){return kZe()},h.$b=function(){EZe()},h.Hc=function(t){return!1},h.Ic=function(t){return!1},h.Jc=function(t){to(this,t)},h.Xb=function(t){return rye((Cn(),t)),null},h.dd=function(t){return-1},h.dc=function(){return!0},h.Kc=function(){return this.a},h.ed=function(){return this.a},h.fd=function(t){return this.a},h.Ti=function(t,n){return TZe()},h.Ui=function(t,n){CZe()},h.Lc=function(){return new bn(null,new kn(this,16))},h.gd=function(t){return SZe()},h.Mc=function(t){return _Ze()},h.hd=function(t,n){return AZe()},h.gc=function(){return 0},h.jd=function(t){$m(this,t)},h.Nc=function(){return new kn(this,16)},h.Oc=function(){return new bn(null,new kn(this,16))},h.kd=function(t,n){return Cn(),new Zp(_o,t,n)},h.Pc=function(){return e5e((Cn(),_o))},h.Qc=function(t){return Cn(),PA(_o,t)},I(So,"ECollections/EmptyUnmodifiableEList",1346),D(1347,783,{20:1,16:1,15:1,61:1,597:1},sJe),h.bd=function(t,n){wZe()},h.Fc=function(t){return yZe()},h.cd=function(t,n){return xZe()},h.Gc=function(t){return kZe()},h.$b=function(){EZe()},h.Hc=function(t){return!1},h.Ic=function(t){return!1},h.Jc=function(t){to(this,t)},h.Xb=function(t){return rye((Cn(),t)),null},h.dd=function(t){return-1},h.dc=function(){return!0},h.Kc=function(){return this.a},h.ed=function(){return this.a},h.fd=function(t){return this.a},h.Ti=function(t,n){return TZe()},h.Ui=function(t,n){CZe()},h.Lc=function(){return new bn(null,new kn(this,16))},h.gd=function(t){return SZe()},h.Mc=function(t){return _Ze()},h.hd=function(t,n){return AZe()},h.gc=function(){return 0},h.jd=function(t){$m(this,t)},h.Nc=function(){return new kn(this,16)},h.Oc=function(){return new bn(null,new kn(this,16))},h.kd=function(t,n){return Cn(),new Zp(_o,t,n)},h.Pc=function(){return e5e((Cn(),_o))},h.Qc=function(t){return Cn(),PA(_o,t)},h.bk=function(){return Cn(),Cn(),mg},I(So,"ECollections/EmptyUnmodifiableEMap",1347);var yPe=ks(So,"Enumerator"),kY;D(288,1,{288:1},ele),h.Fb=function(t){var n;return this===t?!0:De(t,288)?(n=l(t,288),this.f==n.f&&Gdn(this.i,n.i)&&_ae(this.a,this.f&256?n.f&256?n.a:null:n.f&256?null:n.a)&&_ae(this.d,n.d)&&_ae(this.g,n.g)&&_ae(this.e,n.e)&&b6n(this,n)):!1},h.Hb=function(){return this.f},h.Ib=function(){return bmt(this)},h.f=0;var D_t=0,I_t=0,O_t=0,N_t=0,xPe=0,kPe=0,EPe=0,TPe=0,CPe=0,P_t,$M=0,zM=0,B_t=0,F_t=0,EY,SPe;I(So,"URI",288),D(1121,45,m6,aJe),h.zc=function(t,n){return l(rc(this,ei(t),l(n,288)),288)},I(So,"URI/URICache",1121),D(506,66,Bd,E$,uH),h.Si=function(){return!0},I(So,"UniqueEList",506),D(590,63,lp,nV),I(So,"WrappedException",590);var mi=ks(pf,r5t),M4=ks(pf,i5t),dl=ks(pf,s5t),D4=ks(pf,a5t),l1=ks(pf,o5t),Vf=ks(pf,"EClass"),tpe=ks(pf,"EDataType"),R_t;D(1233,45,m6,oJe),h.xc=function(t){return Ia(t)?xu(this,t):hc(zo(this.f,t))},I(pf,"EDataType/Internal/ConversionDelegate/Factory/Registry/Impl",1233);var TY=ks(pf,"EEnum"),wp=ks(pf,c5t),Wo=ks(pf,u5t),Uf=ks(pf,l5t),Gf,k3=ks(pf,h5t),I4=ks(pf,f5t);D(1042,1,{},Yne),h.Ib=function(){return"NIL"},I(pf,"EStructuralFeature/Internal/DynamicValueHolder/1",1042);var j_t;D(1041,45,m6,cJe),h.xc=function(t){return Ia(t)?xu(this,t):hc(zo(this.f,t))},I(pf,"EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl",1041);var Zu=ks(pf,d5t),o9=ks(pf,"EValidator/PatternMatcher"),_Pe,APe,Vn,M2,O4,Jb,$_t,z_t,q_t,Zb,D2,em,E3,td,H_t,V_t,Kf,I2,U_t,O2,N4,o7,No,G_t,K_t,T3,CY=ks(us,"FeatureMap/Entry");D(545,1,{76:1},Sq),h.Lk=function(){return this.a},h.md=function(){return this.b},I(Gn,"BasicEObjectImpl/1",545),D(1040,1,i0e,Itt),h.Fk=function(t){return Moe(this.a,this.b,t)},h.Qj=function(){return got(this.a,this.b)},h.Wb=function(t){q5e(this.a,this.b,t)},h.Gk=function(){Hgn(this.a,this.b)},I(Gn,"BasicEObjectImpl/4",1040),D(2081,1,{114:1}),h.Mk=function(t){this.e=t==0?W_t:We(wa,Rn,1,t,5,1)},h.li=function(t){return this.e[t]},h.mi=function(t,n){this.e[t]=n},h.ni=function(t){this.e[t]=null},h.Nk=function(){return this.c},h.Ok=function(){throw ue(new Qr)},h.Pk=function(){throw ue(new Qr)},h.Qk=function(){return this.d},h.Rk=function(){return this.e!=null},h.Sk=function(t){this.c=t},h.Tk=function(t){throw ue(new Qr)},h.Uk=function(t){throw ue(new Qr)},h.Vk=function(t){this.d=t};var W_t;I(Gn,"BasicEObjectImpl/EPropertiesHolderBaseImpl",2081),D(192,2081,{114:1},Sf),h.Ok=function(){return this.a},h.Pk=function(){return this.b},h.Tk=function(t){this.a=t},h.Uk=function(t){this.b=t},I(Gn,"BasicEObjectImpl/EPropertiesHolderImpl",192),D(516,99,g4t,m5),h.uh=function(){return this.f},h.zh=function(){return this.k},h.Bh=function(t,n){this.g=t,this.i=n},h.Dh=function(){return this.j&2?this.$h().Nk():this.ii()},h.Fh=function(){return this.i},h.wh=function(){return(this.j&1)!=0},h.Ph=function(){return this.g},h.Vh=function(){return(this.j&4)!=0},h.$h=function(){return!this.k&&(this.k=new Sf),this.k},h.ci=function(t){this.$h().Sk(t),t?this.j|=2:this.j&=-3},h.ei=function(t){this.$h().Uk(t),t?this.j|=4:this.j&=-5},h.ii=function(){return(lb(),Vn).S},h.i=0,h.j=1,I(Gn,"EObjectImpl",516),D(798,516,{110:1,94:1,93:1,58:1,114:1,54:1,99:1},F4e),h.li=function(t){return this.e[t]},h.mi=function(t,n){this.e[t]=n},h.ni=function(t){this.e[t]=null},h.Dh=function(){return this.d},h.Ih=function(t){return ms(this.d,t)},h.Kh=function(){return this.d},h.Oh=function(){return this.e!=null},h.$h=function(){return!this.k&&(this.k=new _$),this.k},h.ci=function(t){this.d=t},h.hi=function(){var t;return this.e==null&&(t=yr(this.d),this.e=t==0?Y_t:We(wa,Rn,1,t,5,1)),this},h.ji=function(){return 0};var Y_t;I(Gn,"DynamicEObjectImpl",798),D(1522,798,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1},Git),h.Fb=function(t){return this===t},h.Hb=function(){return fw(this)},h.ci=function(t){this.d=t,this.b=oP(t,"key"),this.c=oP(t,TL)},h.Bi=function(){var t;return this.a==-1&&(t=Hoe(this,this.b),this.a=t==null?0:es(t)),this.a},h.ld=function(){return Hoe(this,this.b)},h.md=function(){return Hoe(this,this.c)},h.Ci=function(t){this.a=t},h.Di=function(t){q5e(this,this.b,t)},h.nd=function(t){var n;return n=Hoe(this,this.c),q5e(this,this.c,t),n},h.a=0,I(Gn,"DynamicEObjectImpl/BasicEMapEntry",1522),D(1523,1,{114:1},_$),h.Mk=function(t){throw ue(new Qr)},h.li=function(t){throw ue(new Qr)},h.mi=function(t,n){throw ue(new Qr)},h.ni=function(t){throw ue(new Qr)},h.Nk=function(){throw ue(new Qr)},h.Ok=function(){return this.a},h.Pk=function(){return this.b},h.Qk=function(){return this.c},h.Rk=function(){throw ue(new Qr)},h.Sk=function(t){throw ue(new Qr)},h.Tk=function(t){this.a=t},h.Uk=function(t){this.b=t},h.Vk=function(t){this.c=t},I(Gn,"DynamicEObjectImpl/DynamicEPropertiesHolderImpl",1523),D(519,158,{110:1,94:1,93:1,598:1,155:1,58:1,114:1,54:1,99:1,519:1,158:1,119:1,120:1},CI),h.Ah=function(t){return dxe(this,t)},h.Lh=function(t,n,r){var a;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.d;case 2:return r?(!this.b&&(this.b=new dh((Tn(),No),Yc,this)),this.b):(!this.b&&(this.b=new dh((Tn(),No),Yc,this)),iN(this.b));case 3:return wot(this);case 4:return!this.a&&(this.a=new Ys(Xb,this,4)),this.a;case 5:return!this.c&&(this.c=new $5(Xb,this,5)),this.c}return sf(this,t-yr((Tn(),M2)),Mn((a=l(Kn(this,16),29),a||M2),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 3:return this.Cb&&(r=(o=this.Db>>16,o>=0?dxe(this,r):this.Cb.Th(this,-1-o,null,r))),Z4e(this,l(t,155),r)}return f=l(Mn((a=l(Kn(this,16),29),a||(Tn(),M2)),n),69),f.wk().zk(this,Ku(this),n-yr((Tn(),M2)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 2:return!this.b&&(this.b=new dh((Tn(),No),Yc,this)),Uq(this.b,t,r);case 3:return Z4e(this,null,r);case 4:return!this.a&&(this.a=new Ys(Xb,this,4)),To(this.a,t,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),M2)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),M2)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.d!=null;case 2:return!!this.b&&this.b.f!=0;case 3:return!!wot(this);case 4:return!!this.a&&this.a.i!=0;case 5:return!!this.c&&this.c.i!=0}return nf(this,t-yr((Tn(),M2)),Mn((n=l(Kn(this,16),29),n||M2),t))},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:Odn(this,ei(n));return;case 2:!this.b&&(this.b=new dh((Tn(),No),Yc,this)),_V(this.b,n);return;case 3:ibt(this,l(n,155));return;case 4:!this.a&&(this.a=new Ys(Xb,this,4)),$r(this.a),!this.a&&(this.a=new Ys(Xb,this,4)),As(this.a,l(n,16));return;case 5:!this.c&&(this.c=new $5(Xb,this,5)),$r(this.c),!this.c&&(this.c=new $5(Xb,this,5)),As(this.c,l(n,16));return}uf(this,t-yr((Tn(),M2)),Mn((r=l(Kn(this,16),29),r||M2),t),n)},h.ii=function(){return Tn(),M2},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:g7e(this,null);return;case 2:!this.b&&(this.b=new dh((Tn(),No),Yc,this)),this.b.c.$b();return;case 3:ibt(this,null);return;case 4:!this.a&&(this.a=new Ys(Xb,this,4)),$r(this.a);return;case 5:!this.c&&(this.c=new $5(Xb,this,5)),$r(this.c);return}cf(this,t-yr((Tn(),M2)),Mn((n=l(Kn(this,16),29),n||M2),t))},h.Ib=function(){return c1t(this)},h.d=null,I(Gn,"EAnnotationImpl",519),D(141,721,ASe,xl),h.Gi=function(t,n){Qln(this,t,l(n,44))},h.Wk=function(t,n){return Zfn(this,l(t,44),n)},h.$i=function(t){return l(l(this.c,71).$i(t),136)},h.Ii=function(){return l(this.c,71).Ii()},h.Ji=function(){return l(this.c,71).Ji()},h.Ki=function(t){return l(this.c,71).Ki(t)},h.Xk=function(t,n){return Uq(this,t,n)},h.Fk=function(t){return l(this.c,79).Fk(t)},h.ak=function(){},h.Qj=function(){return l(this.c,79).Qj()},h.ck=function(t,n,r){var a;return a=l(Ah(this.b).wi().si(this.b),136),a.Ci(t),a.Di(n),a.nd(r),a},h.dk=function(){return new kwe(this)},h.Wb=function(t){_V(this,t)},h.Gk=function(){l(this.c,79).Gk()},I(us,"EcoreEMap",141),D(165,141,ASe,dh),h._j=function(){var t,n,r,a,o,f;if(this.d==null){for(f=We(vPe,_Se,66,2*this.f+1,0,1),r=this.c.Kc();r.e!=r.i.gc();)n=l(r.Yj(),136),a=n.Bi(),o=(a&Ii)%f.length,t=f[o],!t&&(t=f[o]=new kwe(this)),t.Fc(n);this.d=f}},I(Gn,"EAnnotationImpl/1",165),D(292,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,481:1,54:1,99:1,158:1,292:1,119:1,120:1}),h.Lh=function(t,n,r){var a,o;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Hn(),!!(this.Bb&256);case 3:return Hn(),!!(this.Bb&512);case 4:return pt(this.s);case 5:return pt(this.t);case 6:return Hn(),!!this.Jk();case 7:return Hn(),o=this.s,o>=1;case 8:return n?Of(this):this.r;case 9:return this.q}return sf(this,t-yr(this.ii()),Mn((a=l(Kn(this,16),29),a||this.ii()),t),n,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 9:return qae(this,r)}return o=l(Mn((a=l(Kn(this,16),29),a||this.ii()),n),69),o.wk().Ak(this,Ku(this),n-yr(this.ii()),t,r)},h.Wh=function(t){var n,r;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return(this.Bb&256)==0;case 3:return(this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return this.Jk();case 7:return r=this.s,r>=1;case 8:return!!this.r&&!this.q.e&&yw(this.q).i==0;case 9:return!!this.q&&!(this.r&&!this.q.e&&yw(this.q).i==0)}return nf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.bi=function(t,n){var r,a;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:this.ui(ei(n));return;case 2:c2(this,Rt(Bt(n)));return;case 3:u2(this,Rt(Bt(n)));return;case 4:i2(this,l(n,17).a);return;case 5:this.Zk(l(n,17).a);return;case 8:Gm(this,l(n,142));return;case 9:a=$1(this,l(n,89),null),a&&a.oj();return}uf(this,t-yr(this.ii()),Mn((r=l(Kn(this,16),29),r||this.ii()),t),n)},h.ii=function(){return Tn(),K_t},h.ki=function(t){var n,r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:this.ui(null);return;case 2:c2(this,!0);return;case 3:u2(this,!0);return;case 4:i2(this,0);return;case 5:this.Zk(1);return;case 8:Gm(this,null);return;case 9:r=$1(this,null,null),r&&r.oj();return}cf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.pi=function(){Of(this),this.Bb|=1},h.Hk=function(){return Of(this)},h.Ik=function(){return this.t},h.Jk=function(){var t;return t=this.t,t>1||t==-1},h.Si=function(){return(this.Bb&512)!=0},h.Yk=function(t,n){return o8e(this,t,n)},h.Zk=function(t){My(this,t)},h.Ib=function(){return T9e(this)},h.s=0,h.t=1,I(Gn,"ETypedElementImpl",292),D(462,292,{110:1,94:1,93:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,462:1,292:1,119:1,120:1,692:1}),h.Ah=function(t){return Qdt(this,t)},h.Lh=function(t,n,r){var a,o;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Hn(),!!(this.Bb&256);case 3:return Hn(),!!(this.Bb&512);case 4:return pt(this.s);case 5:return pt(this.t);case 6:return Hn(),!!this.Jk();case 7:return Hn(),o=this.s,o>=1;case 8:return n?Of(this):this.r;case 9:return this.q;case 10:return Hn(),!!(this.Bb&m0);case 11:return Hn(),!!(this.Bb&r4);case 12:return Hn(),!!(this.Bb&Xy);case 13:return this.j;case 14:return UE(this);case 15:return Hn(),!!(this.Bb&Sl);case 16:return Hn(),!!(this.Bb&_d);case 17:return ky(this)}return sf(this,t-yr(this.ii()),Mn((a=l(Kn(this,16),29),a||this.ii()),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 17:return this.Cb&&(r=(o=this.Db>>16,o>=0?Qdt(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,17,r)}return f=l(Mn((a=l(Kn(this,16),29),a||this.ii()),n),69),f.wk().zk(this,Ku(this),n-yr(this.ii()),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 9:return qae(this,r);case 17:return Nh(this,null,17,r)}return o=l(Mn((a=l(Kn(this,16),29),a||this.ii()),n),69),o.wk().Ak(this,Ku(this),n-yr(this.ii()),t,r)},h.Wh=function(t){var n,r;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return(this.Bb&256)==0;case 3:return(this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return this.Jk();case 7:return r=this.s,r>=1;case 8:return!!this.r&&!this.q.e&&yw(this.q).i==0;case 9:return!!this.q&&!(this.r&&!this.q.e&&yw(this.q).i==0);case 10:return(this.Bb&m0)==0;case 11:return(this.Bb&r4)!=0;case 12:return(this.Bb&Xy)!=0;case 13:return this.j!=null;case 14:return UE(this)!=null;case 15:return(this.Bb&Sl)!=0;case 16:return(this.Bb&_d)!=0;case 17:return!!ky(this)}return nf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.bi=function(t,n){var r,a;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:poe(this,ei(n));return;case 2:c2(this,Rt(Bt(n)));return;case 3:u2(this,Rt(Bt(n)));return;case 4:i2(this,l(n,17).a);return;case 5:this.Zk(l(n,17).a);return;case 8:Gm(this,l(n,142));return;case 9:a=$1(this,l(n,89),null),a&&a.oj();return;case 10:AE(this,Rt(Bt(n)));return;case 11:DE(this,Rt(Bt(n)));return;case 12:LE(this,Rt(Bt(n)));return;case 13:Z3e(this,ei(n));return;case 15:ME(this,Rt(Bt(n)));return;case 16:IE(this,Rt(Bt(n)));return}uf(this,t-yr(this.ii()),Mn((r=l(Kn(this,16),29),r||this.ii()),t),n)},h.ii=function(){return Tn(),G_t},h.ki=function(t){var n,r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:De(this.Cb,90)&&zy(Yl(l(this.Cb,90)),4),Fu(this,null);return;case 2:c2(this,!0);return;case 3:u2(this,!0);return;case 4:i2(this,0);return;case 5:this.Zk(1);return;case 8:Gm(this,null);return;case 9:r=$1(this,null,null),r&&r.oj();return;case 10:AE(this,!0);return;case 11:DE(this,!1);return;case 12:LE(this,!1);return;case 13:this.i=null,xV(this,null);return;case 15:ME(this,!1);return;case 16:IE(this,!1);return}cf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.pi=function(){Wk(ic((El(),io),this)),Of(this),this.Bb|=1},h.pk=function(){return this.f},h.ik=function(){return UE(this)},h.qk=function(){return ky(this)},h.uk=function(){return null},h.$k=function(){return this.k},h.Lj=function(){return this.n},h.vk=function(){return pU(this)},h.wk=function(){var t,n,r,a,o,f,g,w,E;return this.p||(r=ky(this),(r.i==null&&Sd(r),r.i).length,a=this.uk(),a&&yr(ky(a)),o=Of(this),g=o.kk(),t=g?g.i&1?g==ih?Ns:g==Vr?ro:g==B4?_T:g==Na?ta:g==nm?r3:g==h7?i3:g==Al?jx:PL:g:null,n=UE(this),w=o.ik(),K4n(this),this.Bb&_d&&((f=yxe((El(),io),r))&&f!=this||(f=rx(ic(io,this))))?this.p=new Ntt(this,f):this.Jk()?this.al()?a?this.Bb&Sl?t?this.bl()?this.p=new Om(47,t,this,a):this.p=new Om(5,t,this,a):this.bl()?this.p=new Rm(46,this,a):this.p=new Rm(4,this,a):t?this.bl()?this.p=new Om(49,t,this,a):this.p=new Om(7,t,this,a):this.bl()?this.p=new Rm(48,this,a):this.p=new Rm(6,this,a):this.Bb&Sl?t?t==uv?this.p=new Xp(50,A_t,this):this.bl()?this.p=new Xp(43,t,this):this.p=new Xp(1,t,this):this.bl()?this.p=new Jp(42,this):this.p=new Jp(0,this):t?t==uv?this.p=new Xp(41,A_t,this):this.bl()?this.p=new Xp(45,t,this):this.p=new Xp(3,t,this):this.bl()?this.p=new Jp(44,this):this.p=new Jp(2,this):De(o,156)?t==CY?this.p=new Jp(40,this):this.Bb&512?this.Bb&Sl?t?this.p=new Xp(9,t,this):this.p=new Jp(8,this):t?this.p=new Xp(11,t,this):this.p=new Jp(10,this):this.Bb&Sl?t?this.p=new Xp(13,t,this):this.p=new Jp(12,this):t?this.p=new Xp(15,t,this):this.p=new Jp(14,this):a?(E=a.t,E>1||E==-1?this.bl()?this.Bb&Sl?t?this.p=new Om(25,t,this,a):this.p=new Rm(24,this,a):t?this.p=new Om(27,t,this,a):this.p=new Rm(26,this,a):this.Bb&Sl?t?this.p=new Om(29,t,this,a):this.p=new Rm(28,this,a):t?this.p=new Om(31,t,this,a):this.p=new Rm(30,this,a):this.bl()?this.Bb&Sl?t?this.p=new Om(33,t,this,a):this.p=new Rm(32,this,a):t?this.p=new Om(35,t,this,a):this.p=new Rm(34,this,a):this.Bb&Sl?t?this.p=new Om(37,t,this,a):this.p=new Rm(36,this,a):t?this.p=new Om(39,t,this,a):this.p=new Rm(38,this,a)):this.bl()?this.Bb&Sl?t?this.p=new Xp(17,t,this):this.p=new Jp(16,this):t?this.p=new Xp(19,t,this):this.p=new Jp(18,this):this.Bb&Sl?t?this.p=new Xp(21,t,this):this.p=new Jp(20,this):t?this.p=new Xp(23,t,this):this.p=new Jp(22,this):this._k()?this.bl()?this.p=new kit(l(o,29),this,a):this.p=new $5e(l(o,29),this,a):De(o,156)?t==CY?this.p=new Jp(40,this):this.Bb&Sl?t?this.p=new xst(n,w,this,(Wce(),g==Vr?PPe:g==ih?MPe:g==nm?BPe:g==B4?NPe:g==Na?OPe:g==h7?FPe:g==Al?DPe:g==kf?IPe:ipe)):this.p=new Nat(l(o,156),n,w,this):t?this.p=new yst(n,w,this,(Wce(),g==Vr?PPe:g==ih?MPe:g==nm?BPe:g==B4?NPe:g==Na?OPe:g==h7?FPe:g==Al?DPe:g==kf?IPe:ipe)):this.p=new Oat(l(o,156),n,w,this):this.al()?a?this.Bb&Sl?this.bl()?this.p=new Tit(l(o,29),this,a):this.p=new C4e(l(o,29),this,a):this.bl()?this.p=new Eit(l(o,29),this,a):this.p=new yae(l(o,29),this,a):this.Bb&Sl?this.bl()?this.p=new yrt(l(o,29),this):this.p=new jye(l(o,29),this):this.bl()?this.p=new wrt(l(o,29),this):this.p=new oae(l(o,29),this):this.bl()?a?this.Bb&Sl?this.p=new Cit(l(o,29),this,a):this.p=new E4e(l(o,29),this,a):this.Bb&Sl?this.p=new xrt(l(o,29),this):this.p=new $ye(l(o,29),this):a?this.Bb&Sl?this.p=new Sit(l(o,29),this,a):this.p=new T4e(l(o,29),this,a):this.Bb&Sl?this.p=new krt(l(o,29),this):this.p=new cH(l(o,29),this)),this.p},h.rk=function(){return(this.Bb&m0)!=0},h._k=function(){return!1},h.al=function(){return!1},h.sk=function(){return(this.Bb&_d)!=0},h.xk=function(){return Voe(this)},h.bl=function(){return!1},h.tk=function(){return(this.Bb&Sl)!=0},h.cl=function(t){this.k=t},h.ui=function(t){poe(this,t)},h.Ib=function(){return BU(this)},h.e=!1,h.n=0,I(Gn,"EStructuralFeatureImpl",462),D(331,462,{110:1,94:1,93:1,35:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,331:1,158:1,462:1,292:1,119:1,120:1,692:1},zie),h.Lh=function(t,n,r){var a,o;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Hn(),!!(this.Bb&256);case 3:return Hn(),!!(this.Bb&512);case 4:return pt(this.s);case 5:return pt(this.t);case 6:return Hn(),!!v9e(this);case 7:return Hn(),o=this.s,o>=1;case 8:return n?Of(this):this.r;case 9:return this.q;case 10:return Hn(),!!(this.Bb&m0);case 11:return Hn(),!!(this.Bb&r4);case 12:return Hn(),!!(this.Bb&Xy);case 13:return this.j;case 14:return UE(this);case 15:return Hn(),!!(this.Bb&Sl);case 16:return Hn(),!!(this.Bb&_d);case 17:return ky(this);case 18:return Hn(),!!(this.Bb&eu);case 19:return n?gce(this):Fut(this)}return sf(this,t-yr((Tn(),O4)),Mn((a=l(Kn(this,16),29),a||O4),t),n,r)},h.Wh=function(t){var n,r;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return(this.Bb&256)==0;case 3:return(this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return v9e(this);case 7:return r=this.s,r>=1;case 8:return!!this.r&&!this.q.e&&yw(this.q).i==0;case 9:return!!this.q&&!(this.r&&!this.q.e&&yw(this.q).i==0);case 10:return(this.Bb&m0)==0;case 11:return(this.Bb&r4)!=0;case 12:return(this.Bb&Xy)!=0;case 13:return this.j!=null;case 14:return UE(this)!=null;case 15:return(this.Bb&Sl)!=0;case 16:return(this.Bb&_d)!=0;case 17:return!!ky(this);case 18:return(this.Bb&eu)!=0;case 19:return!!Fut(this)}return nf(this,t-yr((Tn(),O4)),Mn((n=l(Kn(this,16),29),n||O4),t))},h.bi=function(t,n){var r,a;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:poe(this,ei(n));return;case 2:c2(this,Rt(Bt(n)));return;case 3:u2(this,Rt(Bt(n)));return;case 4:i2(this,l(n,17).a);return;case 5:JJe(this,l(n,17).a);return;case 8:Gm(this,l(n,142));return;case 9:a=$1(this,l(n,89),null),a&&a.oj();return;case 10:AE(this,Rt(Bt(n)));return;case 11:DE(this,Rt(Bt(n)));return;case 12:LE(this,Rt(Bt(n)));return;case 13:Z3e(this,ei(n));return;case 15:ME(this,Rt(Bt(n)));return;case 16:IE(this,Rt(Bt(n)));return;case 18:$ce(this,Rt(Bt(n)));return}uf(this,t-yr((Tn(),O4)),Mn((r=l(Kn(this,16),29),r||O4),t),n)},h.ii=function(){return Tn(),O4},h.ki=function(t){var n,r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:De(this.Cb,90)&&zy(Yl(l(this.Cb,90)),4),Fu(this,null);return;case 2:c2(this,!0);return;case 3:u2(this,!0);return;case 4:i2(this,0);return;case 5:this.b=0,My(this,1);return;case 8:Gm(this,null);return;case 9:r=$1(this,null,null),r&&r.oj();return;case 10:AE(this,!0);return;case 11:DE(this,!1);return;case 12:LE(this,!1);return;case 13:this.i=null,xV(this,null);return;case 15:ME(this,!1);return;case 16:IE(this,!1);return;case 18:$ce(this,!1);return}cf(this,t-yr((Tn(),O4)),Mn((n=l(Kn(this,16),29),n||O4),t))},h.pi=function(){gce(this),Wk(ic((El(),io),this)),Of(this),this.Bb|=1},h.Jk=function(){return v9e(this)},h.Yk=function(t,n){return this.b=0,this.a=null,o8e(this,t,n)},h.Zk=function(t){JJe(this,t)},h.Ib=function(){var t;return this.Db&64?BU(this):(t=new Af(BU(this)),t.a+=" (iD: ",Gp(t,(this.Bb&eu)!=0),t.a+=")",t.a)},h.b=0,I(Gn,"EAttributeImpl",331),D(364,448,{110:1,94:1,93:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,364:1,158:1,119:1,120:1,691:1}),h.dl=function(t){return t.Dh()==this},h.Ah=function(t){return wue(this,t)},h.Bh=function(t,n){this.w=null,this.Db=n<<16|this.Db&255,this.Cb=t},h.Lh=function(t,n,r){var a;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return zw(this);case 4:return this.ik();case 5:return this.F;case 6:return n?Ah(this):Qk(this);case 7:return!this.A&&(this.A=new ml(Zu,this,7)),this.A}return sf(this,t-yr(this.ii()),Mn((a=l(Kn(this,16),29),a||this.ii()),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 6:return this.Cb&&(r=(o=this.Db>>16,o>=0?wue(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,6,r)}return f=l(Mn((a=l(Kn(this,16),29),a||this.ii()),n),69),f.wk().zk(this,Ku(this),n-yr(this.ii()),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 6:return Nh(this,null,6,r);case 7:return!this.A&&(this.A=new ml(Zu,this,7)),To(this.A,t,r)}return o=l(Mn((a=l(Kn(this,16),29),a||this.ii()),n),69),o.wk().Ak(this,Ku(this),n-yr(this.ii()),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return!!zw(this);case 4:return this.ik()!=null;case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return!!Qk(this);case 7:return!!this.A&&this.A.i!=0}return nf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:FH(this,ei(n));return;case 2:Kse(this,ei(n));return;case 5:JE(this,ei(n));return;case 7:!this.A&&(this.A=new ml(Zu,this,7)),$r(this.A),!this.A&&(this.A=new ml(Zu,this,7)),As(this.A,l(n,16));return}uf(this,t-yr(this.ii()),Mn((r=l(Kn(this,16),29),r||this.ii()),t),n)},h.ii=function(){return Tn(),$_t},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:De(this.Cb,184)&&(l(this.Cb,184).tb=null),Fu(this,null);return;case 2:CE(this,null),lE(this,this.D);return;case 5:JE(this,null);return;case 7:!this.A&&(this.A=new ml(Zu,this,7)),$r(this.A);return}cf(this,t-yr(this.ii()),Mn((n=l(Kn(this,16),29),n||this.ii()),t))},h.hk=function(){var t;return this.G==-1&&(this.G=(t=Ah(this),t?f2(t.vi(),this):-1)),this.G},h.ik=function(){return null},h.jk=function(){return Ah(this)},h.el=function(){return this.v},h.kk=function(){return zw(this)},h.lk=function(){return this.D!=null?this.D:this.B},h.mk=function(){return this.F},h.fk=function(t){return ule(this,t)},h.fl=function(t){this.v=t},h.gl=function(t){xft(this,t)},h.hl=function(t){this.C=t},h.ui=function(t){FH(this,t)},h.Ib=function(){return UV(this)},h.C=null,h.D=null,h.G=-1,I(Gn,"EClassifierImpl",364),D(90,364,{110:1,94:1,93:1,29:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,90:1,364:1,158:1,482:1,119:1,120:1,691:1},hz),h.dl=function(t){return Bfn(this,t.Dh())},h.Lh=function(t,n,r){var a;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return zw(this);case 4:return null;case 5:return this.F;case 6:return n?Ah(this):Qk(this);case 7:return!this.A&&(this.A=new ml(Zu,this,7)),this.A;case 8:return Hn(),!!(this.Bb&256);case 9:return Hn(),!!(this.Bb&512);case 10:return dc(this);case 11:return!this.q&&(this.q=new nt(Uf,this,11,10)),this.q;case 12:return d6(this);case 13:return JA(this);case 14:return JA(this),this.r;case 15:return d6(this),this.k;case 16:return o9e(this);case 17:return dle(this);case 18:return Sd(this);case 19:return _U(this);case 20:return d6(this),this.o;case 21:return!this.s&&(this.s=new nt(dl,this,21,17)),this.s;case 22:return du(this);case 23:return Zue(this)}return sf(this,t-yr((Tn(),Jb)),Mn((a=l(Kn(this,16),29),a||Jb),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 6:return this.Cb&&(r=(o=this.Db>>16,o>=0?wue(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,6,r);case 11:return!this.q&&(this.q=new nt(Uf,this,11,10)),Ru(this.q,t,r);case 21:return!this.s&&(this.s=new nt(dl,this,21,17)),Ru(this.s,t,r)}return f=l(Mn((a=l(Kn(this,16),29),a||(Tn(),Jb)),n),69),f.wk().zk(this,Ku(this),n-yr((Tn(),Jb)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 6:return Nh(this,null,6,r);case 7:return!this.A&&(this.A=new ml(Zu,this,7)),To(this.A,t,r);case 11:return!this.q&&(this.q=new nt(Uf,this,11,10)),To(this.q,t,r);case 21:return!this.s&&(this.s=new nt(dl,this,21,17)),To(this.s,t,r);case 22:return To(du(this),t,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),Jb)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),Jb)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return!!zw(this);case 4:return!1;case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return!!Qk(this);case 7:return!!this.A&&this.A.i!=0;case 8:return(this.Bb&256)!=0;case 9:return(this.Bb&512)!=0;case 10:return!!this.u&&du(this.u.a).i!=0&&!(this.n&&cue(this.n));case 11:return!!this.q&&this.q.i!=0;case 12:return d6(this).i!=0;case 13:return JA(this).i!=0;case 14:return JA(this),this.r.i!=0;case 15:return d6(this),this.k.i!=0;case 16:return o9e(this).i!=0;case 17:return dle(this).i!=0;case 18:return Sd(this).i!=0;case 19:return _U(this).i!=0;case 20:return d6(this),!!this.o;case 21:return!!this.s&&this.s.i!=0;case 22:return!!this.n&&cue(this.n);case 23:return Zue(this).i!=0}return nf(this,t-yr((Tn(),Jb)),Mn((n=l(Kn(this,16),29),n||Jb),t))},h.Zh=function(t){var n;return n=this.i==null||this.q&&this.q.i!=0?null:oP(this,t),n||Hke(this,t)},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:FH(this,ei(n));return;case 2:Kse(this,ei(n));return;case 5:JE(this,ei(n));return;case 7:!this.A&&(this.A=new ml(Zu,this,7)),$r(this.A),!this.A&&(this.A=new ml(Zu,this,7)),As(this.A,l(n,16));return;case 8:c8e(this,Rt(Bt(n)));return;case 9:u8e(this,Rt(Bt(n)));return;case 10:tL(dc(this)),As(dc(this),l(n,16));return;case 11:!this.q&&(this.q=new nt(Uf,this,11,10)),$r(this.q),!this.q&&(this.q=new nt(Uf,this,11,10)),As(this.q,l(n,16));return;case 21:!this.s&&(this.s=new nt(dl,this,21,17)),$r(this.s),!this.s&&(this.s=new nt(dl,this,21,17)),As(this.s,l(n,16));return;case 22:$r(du(this)),As(du(this),l(n,16));return}uf(this,t-yr((Tn(),Jb)),Mn((r=l(Kn(this,16),29),r||Jb),t),n)},h.ii=function(){return Tn(),Jb},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:De(this.Cb,184)&&(l(this.Cb,184).tb=null),Fu(this,null);return;case 2:CE(this,null),lE(this,this.D);return;case 5:JE(this,null);return;case 7:!this.A&&(this.A=new ml(Zu,this,7)),$r(this.A);return;case 8:c8e(this,!1);return;case 9:u8e(this,!1);return;case 10:this.u&&tL(this.u);return;case 11:!this.q&&(this.q=new nt(Uf,this,11,10)),$r(this.q);return;case 21:!this.s&&(this.s=new nt(dl,this,21,17)),$r(this.s);return;case 22:this.n&&$r(this.n);return}cf(this,t-yr((Tn(),Jb)),Mn((n=l(Kn(this,16),29),n||Jb),t))},h.pi=function(){var t,n;if(d6(this),JA(this),o9e(this),dle(this),Sd(this),_U(this),Zue(this),uA(cdn(Yl(this))),this.s)for(t=0,n=this.s.i;t=0;--n)Oe(this,n);return O8e(this,t)},h.Gk=function(){$r(this)},h.Zi=function(t,n){return Hht(this,t,n)},I(us,"EcoreEList",632),D(505,632,kc,FO),h.Li=function(){return!1},h.Lj=function(){return this.c},h.Mj=function(){return!1},h.ol=function(){return!0},h.Si=function(){return!0},h.Wi=function(t,n){return n},h.Yi=function(){return!1},h.c=0,I(us,"EObjectEList",505),D(83,505,kc,Ys),h.Mj=function(){return!0},h.ml=function(){return!1},h.al=function(){return!0},I(us,"EObjectContainmentEList",83),D(555,83,kc,Bq),h.Ni=function(){this.b=!0},h.Qj=function(){return this.b},h.Gk=function(){var t;$r(this),hh(this.e)?(t=this.b,this.b=!1,Ni(this.e,new h0(this.e,2,this.c,t,!1))):this.b=!1},h.b=!1,I(us,"EObjectContainmentEList/Unsettable",555),D(1161,555,kc,vst),h.Ti=function(t,n){var r,a;return r=l(AA(this,t,n),89),hh(this.e)&&xk(this,new sN(this.a,7,(Tn(),z_t),pt(n),(a=r.c,De(a,90)?l(a,29):Kf),t)),r},h.Uj=function(t,n){return L5n(this,l(t,89),n)},h.Vj=function(t,n){return A5n(this,l(t,89),n)},h.Wj=function(t,n,r){return I8n(this,l(t,89),l(n,89),r)},h.Ij=function(t,n,r,a,o){switch(t){case 3:return rA(this,t,n,r,a,this.i>1);case 5:return rA(this,t,n,r,a,this.i-l(r,15).gc()>0);default:return new Zg(this.e,t,this.c,n,r,a,!0)}},h.Tj=function(){return!0},h.Qj=function(){return cue(this)},h.Gk=function(){$r(this)},I(Gn,"EClassImpl/1",1161),D(1175,1174,SSe),h.dj=function(t){var n,r,a,o,f,g,w;if(r=t.gj(),r!=8){if(a=l6n(t),a==0)switch(r){case 1:case 9:{w=t.kj(),w!=null&&(n=Yl(l(w,482)),!n.c&&(n.c=new Xd),sV(n.c,t.jj())),g=t.ij(),g!=null&&(o=l(g,482),o.Bb&1||(n=Yl(o),!n.c&&(n.c=new Xd),qr(n.c,l(t.jj(),29))));break}case 3:{g=t.ij(),g!=null&&(o=l(g,482),o.Bb&1||(n=Yl(o),!n.c&&(n.c=new Xd),qr(n.c,l(t.jj(),29))));break}case 5:{if(g=t.ij(),g!=null)for(f=l(g,16).Kc();f.Ob();)o=l(f.Pb(),482),o.Bb&1||(n=Yl(o),!n.c&&(n.c=new Xd),qr(n.c,l(t.jj(),29)));break}case 4:{w=t.kj(),w!=null&&(o=l(w,482),o.Bb&1||(n=Yl(o),!n.c&&(n.c=new Xd),sV(n.c,t.jj())));break}case 6:{if(w=t.kj(),w!=null)for(f=l(w,16).Kc();f.Ob();)o=l(f.Pb(),482),o.Bb&1||(n=Yl(o),!n.c&&(n.c=new Xd),sV(n.c,t.jj()));break}}this.ql(a)}},h.ql=function(t){Vbt(this,t)},h.b=63,I(Gn,"ESuperAdapter",1175),D(1176,1175,SSe,bQe),h.ql=function(t){zy(this,t)},I(Gn,"EClassImpl/10",1176),D(1165,710,kc),h.Ei=function(t,n){return Due(this,t,n)},h.Fi=function(t){return Odt(this,t)},h.Gi=function(t,n){IN(this,t,n)},h.Hi=function(t){tN(this,t)},h.$i=function(t){return R6e(this,t)},h.Xi=function(t,n){return Uoe(this,t,n)},h.Wk=function(t,n){throw ue(new Qr)},h.Ii=function(){return new H8(this)},h.Ji=function(){return new CO(this)},h.Ki=function(t){return mN(this,t)},h.Xk=function(t,n){throw ue(new Qr)},h.Fk=function(t){return this},h.Qj=function(){return this.i!=0},h.Wb=function(t){throw ue(new Qr)},h.Gk=function(){throw ue(new Qr)},I(us,"EcoreEList/UnmodifiableEList",1165),D(328,1165,kc,N5),h.Yi=function(){return!1},I(us,"EcoreEList/UnmodifiableEList/FastCompare",328),D(1168,328,kc,g0t),h.dd=function(t){var n,r,a;if(De(t,179)&&(n=l(t,179),r=n.Lj(),r!=-1)){for(a=this.i;r4)if(this.fk(t)){if(this.al()){if(a=l(t,54),r=a.Eh(),w=r==this.b&&(this.ml()?a.yh(a.Fh(),l(Mn(sl(this.b),this.Lj()).Hk(),29).kk())==Ro(l(Mn(sl(this.b),this.Lj()),19)).n:-1-a.Fh()==this.Lj()),this.nl()&&!w&&!r&&a.Jh()){for(o=0;o1||a==-1)):!1},h.ml=function(){var t,n,r;return n=Mn(sl(this.b),this.Lj()),De(n,102)?(t=l(n,19),r=Ro(t),!!r):!1},h.nl=function(){var t,n;return n=Mn(sl(this.b),this.Lj()),De(n,102)?(t=l(n,19),(t.Bb&Io)!=0):!1},h.dd=function(t){var n,r,a,o;if(a=this.zj(t),a>=0)return a;if(this.ol()){for(r=0,o=this.Ej();r=0;--t)mP(this,t,this.xj(t));return this.Fj()},h.Qc=function(t){var n;if(this.nl())for(n=this.Ej()-1;n>=0;--n)mP(this,n,this.xj(n));return this.Gj(t)},h.Gk=function(){tL(this)},h.Zi=function(t,n){return ylt(this,t,n)},I(us,"DelegatingEcoreEList",756),D(1171,756,MSe,Nrt),h.qj=function(t,n){afn(this,t,l(n,29))},h.rj=function(t){Wln(this,l(t,29))},h.xj=function(t){var n,r;return n=l(Oe(du(this.a),t),89),r=n.c,De(r,90)?l(r,29):(Tn(),Kf)},h.Cj=function(t){var n,r;return n=l(Vy(du(this.a),t),89),r=n.c,De(r,90)?l(r,29):(Tn(),Kf)},h.Dj=function(t,n){return r7n(this,t,l(n,29))},h.Li=function(){return!1},h.Ij=function(t,n,r,a,o){return null},h.sj=function(){return new wQe(this)},h.tj=function(){$r(du(this.a))},h.uj=function(t){return l1t(this,t)},h.vj=function(t){var n,r;for(r=t.Kc();r.Ob();)if(n=r.Pb(),!l1t(this,n))return!1;return!0},h.wj=function(t){var n,r,a;if(De(t,15)&&(a=l(t,15),a.gc()==du(this.a).i)){for(n=a.Kc(),r=new or(this);n.Ob();)if(qe(n.Pb())!==qe(gr(r)))return!1;return!0}return!1},h.yj=function(){var t,n,r,a,o;for(r=1,n=new or(du(this.a));n.e!=n.i.gc();)t=l(gr(n),89),a=(o=t.c,De(o,90)?l(o,29):(Tn(),Kf)),r=31*r+(a?fw(a):0);return r},h.zj=function(t){var n,r,a,o;for(a=0,r=new or(du(this.a));r.e!=r.i.gc();){if(n=l(gr(r),89),qe(t)===qe((o=n.c,De(o,90)?l(o,29):(Tn(),Kf))))return a;++a}return-1},h.Aj=function(){return du(this.a).i==0},h.Bj=function(){return null},h.Ej=function(){return du(this.a).i},h.Fj=function(){var t,n,r,a,o,f;for(f=du(this.a).i,o=We(wa,Rn,1,f,5,1),r=0,n=new or(du(this.a));n.e!=n.i.gc();)t=l(gr(n),89),o[r++]=(a=t.c,De(a,90)?l(a,29):(Tn(),Kf));return o},h.Gj=function(t){var n,r,a,o,f,g,w;for(w=du(this.a).i,t.lengthw&&Ts(t,w,null),a=0,r=new or(du(this.a));r.e!=r.i.gc();)n=l(gr(r),89),f=(g=n.c,De(g,90)?l(g,29):(Tn(),Kf)),Ts(t,a++,f);return t},h.Hj=function(){var t,n,r,a,o;for(o=new Up,o.a+="[",t=du(this.a),n=0,a=du(this.a).i;n>16,o>=0?wue(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,6,r);case 9:return!this.a&&(this.a=new nt(wp,this,9,5)),Ru(this.a,t,r)}return f=l(Mn((a=l(Kn(this,16),29),a||(Tn(),Zb)),n),69),f.wk().zk(this,Ku(this),n-yr((Tn(),Zb)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 6:return Nh(this,null,6,r);case 7:return!this.A&&(this.A=new ml(Zu,this,7)),To(this.A,t,r);case 9:return!this.a&&(this.a=new nt(wp,this,9,5)),To(this.a,t,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),Zb)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),Zb)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return!!zw(this);case 4:return!!X7e(this);case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return!!Qk(this);case 7:return!!this.A&&this.A.i!=0;case 8:return(this.Bb&256)==0;case 9:return!!this.a&&this.a.i!=0}return nf(this,t-yr((Tn(),Zb)),Mn((n=l(Kn(this,16),29),n||Zb),t))},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:FH(this,ei(n));return;case 2:Kse(this,ei(n));return;case 5:JE(this,ei(n));return;case 7:!this.A&&(this.A=new ml(Zu,this,7)),$r(this.A),!this.A&&(this.A=new ml(Zu,this,7)),As(this.A,l(n,16));return;case 8:jV(this,Rt(Bt(n)));return;case 9:!this.a&&(this.a=new nt(wp,this,9,5)),$r(this.a),!this.a&&(this.a=new nt(wp,this,9,5)),As(this.a,l(n,16));return}uf(this,t-yr((Tn(),Zb)),Mn((r=l(Kn(this,16),29),r||Zb),t),n)},h.ii=function(){return Tn(),Zb},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:De(this.Cb,184)&&(l(this.Cb,184).tb=null),Fu(this,null);return;case 2:CE(this,null),lE(this,this.D);return;case 5:JE(this,null);return;case 7:!this.A&&(this.A=new ml(Zu,this,7)),$r(this.A);return;case 8:jV(this,!0);return;case 9:!this.a&&(this.a=new nt(wp,this,9,5)),$r(this.a);return}cf(this,t-yr((Tn(),Zb)),Mn((n=l(Kn(this,16),29),n||Zb),t))},h.pi=function(){var t,n;if(this.a)for(t=0,n=this.a.i;t>16==5?l(this.Cb,685):null}return sf(this,t-yr((Tn(),D2)),Mn((a=l(Kn(this,16),29),a||D2),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 5:return this.Cb&&(r=(o=this.Db>>16,o>=0?agt(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,5,r)}return f=l(Mn((a=l(Kn(this,16),29),a||(Tn(),D2)),n),69),f.wk().zk(this,Ku(this),n-yr((Tn(),D2)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 5:return Nh(this,null,5,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),D2)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),D2)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.d!=0;case 3:return!!this.b;case 4:return this.c!=null;case 5:return!!(this.Db>>16==5&&l(this.Cb,685))}return nf(this,t-yr((Tn(),D2)),Mn((n=l(Kn(this,16),29),n||D2),t))},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:Fu(this,ei(n));return;case 2:Qoe(this,l(n,17).a);return;case 3:r2t(this,l(n,2039));return;case 4:Zoe(this,ei(n));return}uf(this,t-yr((Tn(),D2)),Mn((r=l(Kn(this,16),29),r||D2),t),n)},h.ii=function(){return Tn(),D2},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:Fu(this,null);return;case 2:Qoe(this,0);return;case 3:r2t(this,null);return;case 4:Zoe(this,null);return}cf(this,t-yr((Tn(),D2)),Mn((n=l(Kn(this,16),29),n||D2),t))},h.Ib=function(){var t;return t=this.c,t??this.zb},h.b=null,h.c=null,h.d=0,I(Gn,"EEnumLiteralImpl",582);var POn=ks(Gn,"EFactoryImpl/InternalEDateTimeFormat");D(499,1,{2114:1},KI),I(Gn,"EFactoryImpl/1ClientInternalEDateTimeFormat",499),D(248,120,{110:1,94:1,93:1,89:1,58:1,114:1,54:1,99:1,248:1,119:1,120:1},Qv),h.Ch=function(t,n,r){var a;return r=Nh(this,t,n,r),this.e&&De(t,179)&&(a=SU(this,this.e),a!=this.c&&(r=ZE(this,a,r))),r},h.Lh=function(t,n,r){var a;switch(t){case 0:return this.f;case 1:return!this.d&&(this.d=new Ys(Wo,this,1)),this.d;case 2:return n?jU(this):this.c;case 3:return this.b;case 4:return this.e;case 5:return n?hue(this):this.a}return sf(this,t-yr((Tn(),E3)),Mn((a=l(Kn(this,16),29),a||E3),t),n,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return Q0t(this,null,r);case 1:return!this.d&&(this.d=new Ys(Wo,this,1)),To(this.d,t,r);case 3:return J0t(this,null,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),E3)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),E3)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.f;case 1:return!!this.d&&this.d.i!=0;case 2:return!!this.c;case 3:return!!this.b;case 4:return!!this.e;case 5:return!!this.a}return nf(this,t-yr((Tn(),E3)),Mn((n=l(Kn(this,16),29),n||E3),t))},h.bi=function(t,n){var r;switch(t){case 0:Cgt(this,l(n,89));return;case 1:!this.d&&(this.d=new Ys(Wo,this,1)),$r(this.d),!this.d&&(this.d=new Ys(Wo,this,1)),As(this.d,l(n,16));return;case 3:Axe(this,l(n,89));return;case 4:Kxe(this,l(n,850));return;case 5:sE(this,l(n,142));return}uf(this,t-yr((Tn(),E3)),Mn((r=l(Kn(this,16),29),r||E3),t),n)},h.ii=function(){return Tn(),E3},h.ki=function(t){var n;switch(t){case 0:Cgt(this,null);return;case 1:!this.d&&(this.d=new Ys(Wo,this,1)),$r(this.d);return;case 3:Axe(this,null);return;case 4:Kxe(this,null);return;case 5:sE(this,null);return}cf(this,t-yr((Tn(),E3)),Mn((n=l(Kn(this,16),29),n||E3),t))},h.Ib=function(){var t;return t=new Th(g0(this)),t.a+=" (expression: ",wle(this,t),t.a+=")",t.a};var LPe;I(Gn,"EGenericTypeImpl",248),D(2067,2062,KG),h.Gi=function(t,n){Drt(this,t,n)},h.Wk=function(t,n){return Drt(this,this.gc(),t),n},h.$i=function(t){return ff(this.pj(),t)},h.Ii=function(){return this.Ji()},h.pj=function(){return new EQe(this)},h.Ji=function(){return this.Ki(0)},h.Ki=function(t){return this.pj().fd(t)},h.Xk=function(t,n){return Ny(this,t,!0),n},h.Ti=function(t,n){var r,a;return a=kue(this,n),r=this.fd(t),r.Rb(a),a},h.Ui=function(t,n){var r;Ny(this,n,!0),r=this.fd(t),r.Rb(n)},I(us,"AbstractSequentialInternalEList",2067),D(496,2067,KG,TO),h.$i=function(t){return ff(this.pj(),t)},h.Ii=function(){return this.b==null?(Wp(),Wp(),dF):this.sl()},h.pj=function(){return new Xtt(this.a,this.b)},h.Ji=function(){return this.b==null?(Wp(),Wp(),dF):this.sl()},h.Ki=function(t){var n,r;if(this.b==null){if(t<0||t>1)throw ue(new tc(CL+t+", size=0"));return Wp(),Wp(),dF}for(r=this.sl(),n=0;n0;)if(n=this.c[--this.d],(!this.e||n.pk()!=oC||n.Lj()!=0)&&(!this.vl()||this.b.Xh(n))){if(f=this.b.Nh(n,this.ul()),this.f=(Fo(),l(n,69).xk()),this.f||n.Jk()){if(this.ul()?(a=l(f,15),this.k=a):(a=l(f,71),this.k=this.j=a),De(this.k,59)?(this.o=this.k.gc(),this.n=this.o):this.p=this.j?this.j.Ki(this.k.gc()):this.k.fd(this.k.gc()),this.p?wpt(this,this.p):Mpt(this))return o=this.p?this.p.Ub():this.j?this.j.$i(--this.n):this.k.Xb(--this.n),this.f?(t=l(o,76),t.Lk(),r=t.md(),this.i=r):(r=o,this.i=r),this.g=-3,!0}else if(f!=null)return this.k=null,this.p=null,r=f,this.i=r,this.g=-2,!0}return this.k=null,this.p=null,this.g=-1,!1}else return o=this.p?this.p.Ub():this.j?this.j.$i(--this.n):this.k.Xb(--this.n),this.f?(t=l(o,76),t.Lk(),r=t.md(),this.i=r):(r=o,this.i=r),this.g=-3,!0}},h.Pb=function(){return MV(this)},h.Tb=function(){return this.a},h.Ub=function(){var t;if(this.g<-1||this.Sb())return--this.a,this.g=0,t=this.i,this.Sb(),t;throw ue(new _c)},h.Vb=function(){return this.a-1},h.Qb=function(){throw ue(new Qr)},h.ul=function(){return!1},h.Wb=function(t){throw ue(new Qr)},h.vl=function(){return!0},h.a=0,h.d=0,h.f=!1,h.g=0,h.n=0,h.o=0;var dF;I(us,"EContentsEList/FeatureIteratorImpl",287),D(711,287,WG,Rye),h.ul=function(){return!0},I(us,"EContentsEList/ResolvingFeatureIteratorImpl",711),D(1178,711,WG,brt),h.vl=function(){return!1},I(Gn,"ENamedElementImpl/1/1",1178),D(1179,287,WG,mrt),h.vl=function(){return!1},I(Gn,"ENamedElementImpl/1/2",1179),D(39,152,YP,Cy,koe,_a,Foe,Zg,h0,Q6e,Xot,J6e,Qot,p6e,Jot,t7e,Zot,b6e,ect,Z6e,tct,X_,sN,roe,e7e,nct,m6e,rct),h.Kj=function(){return N6e(this)},h.Rj=function(){var t;return t=N6e(this),t?t.ik():null},h.hj=function(t){return this.b==-1&&this.a&&(this.b=this.c.Hh(this.a.Lj(),this.a.pk())),this.c.yh(this.b,t)},h.jj=function(){return this.c},h.Sj=function(){var t;return t=N6e(this),t?t.tk():!1},h.b=-1,I(Gn,"ENotificationImpl",39),D(411,292,{110:1,94:1,93:1,155:1,197:1,58:1,62:1,114:1,481:1,54:1,99:1,158:1,411:1,292:1,119:1,120:1},qie),h.Ah=function(t){return ugt(this,t)},h.Lh=function(t,n,r){var a,o,f;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Hn(),!!(this.Bb&256);case 3:return Hn(),!!(this.Bb&512);case 4:return pt(this.s);case 5:return pt(this.t);case 6:return Hn(),f=this.t,f>1||f==-1;case 7:return Hn(),o=this.s,o>=1;case 8:return n?Of(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?l(this.Cb,29):null;case 11:return!this.d&&(this.d=new ml(Zu,this,11)),this.d;case 12:return!this.c&&(this.c=new nt(k3,this,12,10)),this.c;case 13:return!this.a&&(this.a=new LO(this,this)),this.a;case 14:return Xl(this)}return sf(this,t-yr((Tn(),I2)),Mn((a=l(Kn(this,16),29),a||I2),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 10:return this.Cb&&(r=(o=this.Db>>16,o>=0?ugt(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,10,r);case 12:return!this.c&&(this.c=new nt(k3,this,12,10)),Ru(this.c,t,r)}return f=l(Mn((a=l(Kn(this,16),29),a||(Tn(),I2)),n),69),f.wk().zk(this,Ku(this),n-yr((Tn(),I2)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 9:return qae(this,r);case 10:return Nh(this,null,10,r);case 11:return!this.d&&(this.d=new ml(Zu,this,11)),To(this.d,t,r);case 12:return!this.c&&(this.c=new nt(k3,this,12,10)),To(this.c,t,r);case 14:return To(Xl(this),t,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),I2)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),I2)),t,r)},h.Wh=function(t){var n,r,a;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return(this.Bb&256)==0;case 3:return(this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return a=this.t,a>1||a==-1;case 7:return r=this.s,r>=1;case 8:return!!this.r&&!this.q.e&&yw(this.q).i==0;case 9:return!!this.q&&!(this.r&&!this.q.e&&yw(this.q).i==0);case 10:return!!(this.Db>>16==10&&l(this.Cb,29));case 11:return!!this.d&&this.d.i!=0;case 12:return!!this.c&&this.c.i!=0;case 13:return!!this.a&&Xl(this.a.a).i!=0&&!(this.b&&uue(this.b));case 14:return!!this.b&&uue(this.b)}return nf(this,t-yr((Tn(),I2)),Mn((n=l(Kn(this,16),29),n||I2),t))},h.bi=function(t,n){var r,a;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:Fu(this,ei(n));return;case 2:c2(this,Rt(Bt(n)));return;case 3:u2(this,Rt(Bt(n)));return;case 4:i2(this,l(n,17).a);return;case 5:My(this,l(n,17).a);return;case 8:Gm(this,l(n,142));return;case 9:a=$1(this,l(n,89),null),a&&a.oj();return;case 11:!this.d&&(this.d=new ml(Zu,this,11)),$r(this.d),!this.d&&(this.d=new ml(Zu,this,11)),As(this.d,l(n,16));return;case 12:!this.c&&(this.c=new nt(k3,this,12,10)),$r(this.c),!this.c&&(this.c=new nt(k3,this,12,10)),As(this.c,l(n,16));return;case 13:!this.a&&(this.a=new LO(this,this)),tL(this.a),!this.a&&(this.a=new LO(this,this)),As(this.a,l(n,16));return;case 14:$r(Xl(this)),As(Xl(this),l(n,16));return}uf(this,t-yr((Tn(),I2)),Mn((r=l(Kn(this,16),29),r||I2),t),n)},h.ii=function(){return Tn(),I2},h.ki=function(t){var n,r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:Fu(this,null);return;case 2:c2(this,!0);return;case 3:u2(this,!0);return;case 4:i2(this,0);return;case 5:My(this,1);return;case 8:Gm(this,null);return;case 9:r=$1(this,null,null),r&&r.oj();return;case 11:!this.d&&(this.d=new ml(Zu,this,11)),$r(this.d);return;case 12:!this.c&&(this.c=new nt(k3,this,12,10)),$r(this.c);return;case 13:this.a&&tL(this.a);return;case 14:this.b&&$r(this.b);return}cf(this,t-yr((Tn(),I2)),Mn((n=l(Kn(this,16),29),n||I2),t))},h.pi=function(){var t,n;if(this.c)for(t=0,n=this.c.i;tw&&Ts(t,w,null),a=0,r=new or(Xl(this.a));r.e!=r.i.gc();)n=l(gr(r),89),f=(g=n.c,g||(Tn(),td)),Ts(t,a++,f);return t},h.Hj=function(){var t,n,r,a,o;for(o=new Up,o.a+="[",t=Xl(this.a),n=0,a=Xl(this.a).i;n1);case 5:return rA(this,t,n,r,a,this.i-l(r,15).gc()>0);default:return new Zg(this.e,t,this.c,n,r,a,!0)}},h.Tj=function(){return!0},h.Qj=function(){return uue(this)},h.Gk=function(){$r(this)},I(Gn,"EOperationImpl/2",1377),D(507,1,{2037:1,507:1},Ott),I(Gn,"EPackageImpl/1",507),D(14,83,kc,nt),h.il=function(){return this.d},h.jl=function(){return this.b},h.ml=function(){return!0},h.b=0,I(us,"EObjectContainmentWithInverseEList",14),D(365,14,kc,V8),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectContainmentWithInverseEList/Resolving",365),D(308,365,kc,wy),h.Ni=function(){this.a.tb=null},I(Gn,"EPackageImpl/2",308),D(1278,1,{},ere),I(Gn,"EPackageImpl/3",1278),D(733,45,m6,$we),h._b=function(t){return Ia(t)?soe(this,t):!!zo(this.f,t)},I(Gn,"EPackageRegistryImpl",733),D(518,292,{110:1,94:1,93:1,155:1,197:1,58:1,2116:1,114:1,481:1,54:1,99:1,158:1,518:1,292:1,119:1,120:1},Hie),h.Ah=function(t){return lgt(this,t)},h.Lh=function(t,n,r){var a,o,f;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Hn(),!!(this.Bb&256);case 3:return Hn(),!!(this.Bb&512);case 4:return pt(this.s);case 5:return pt(this.t);case 6:return Hn(),f=this.t,f>1||f==-1;case 7:return Hn(),o=this.s,o>=1;case 8:return n?Of(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?l(this.Cb,62):null}return sf(this,t-yr((Tn(),N4)),Mn((a=l(Kn(this,16),29),a||N4),t),n,r)},h.Sh=function(t,n,r){var a,o,f;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),Ru(this.Ab,t,r);case 10:return this.Cb&&(r=(o=this.Db>>16,o>=0?lgt(this,r):this.Cb.Th(this,-1-o,null,r))),Nh(this,t,10,r)}return f=l(Mn((a=l(Kn(this,16),29),a||(Tn(),N4)),n),69),f.wk().zk(this,Ku(this),n-yr((Tn(),N4)),t,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 9:return qae(this,r);case 10:return Nh(this,null,10,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),N4)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),N4)),t,r)},h.Wh=function(t){var n,r,a;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return(this.Bb&256)==0;case 3:return(this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return a=this.t,a>1||a==-1;case 7:return r=this.s,r>=1;case 8:return!!this.r&&!this.q.e&&yw(this.q).i==0;case 9:return!!this.q&&!(this.r&&!this.q.e&&yw(this.q).i==0);case 10:return!!(this.Db>>16==10&&l(this.Cb,62))}return nf(this,t-yr((Tn(),N4)),Mn((n=l(Kn(this,16),29),n||N4),t))},h.ii=function(){return Tn(),N4},I(Gn,"EParameterImpl",518),D(102,462,{110:1,94:1,93:1,155:1,197:1,58:1,19:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,102:1,462:1,292:1,119:1,120:1,692:1},Hye),h.Lh=function(t,n,r){var a,o,f,g;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Hn(),!!(this.Bb&256);case 3:return Hn(),!!(this.Bb&512);case 4:return pt(this.s);case 5:return pt(this.t);case 6:return Hn(),g=this.t,g>1||g==-1;case 7:return Hn(),o=this.s,o>=1;case 8:return n?Of(this):this.r;case 9:return this.q;case 10:return Hn(),!!(this.Bb&m0);case 11:return Hn(),!!(this.Bb&r4);case 12:return Hn(),!!(this.Bb&Xy);case 13:return this.j;case 14:return UE(this);case 15:return Hn(),!!(this.Bb&Sl);case 16:return Hn(),!!(this.Bb&_d);case 17:return ky(this);case 18:return Hn(),!!(this.Bb&eu);case 19:return Hn(),f=Ro(this),!!(f&&f.Bb&eu);case 20:return Hn(),!!(this.Bb&Io);case 21:return n?Ro(this):this.b;case 22:return n?$7e(this):_ut(this);case 23:return!this.a&&(this.a=new $5(D4,this,23)),this.a}return sf(this,t-yr((Tn(),o7)),Mn((a=l(Kn(this,16),29),a||o7),t),n,r)},h.Wh=function(t){var n,r,a,o;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return(this.Bb&256)==0;case 3:return(this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return o=this.t,o>1||o==-1;case 7:return r=this.s,r>=1;case 8:return!!this.r&&!this.q.e&&yw(this.q).i==0;case 9:return!!this.q&&!(this.r&&!this.q.e&&yw(this.q).i==0);case 10:return(this.Bb&m0)==0;case 11:return(this.Bb&r4)!=0;case 12:return(this.Bb&Xy)!=0;case 13:return this.j!=null;case 14:return UE(this)!=null;case 15:return(this.Bb&Sl)!=0;case 16:return(this.Bb&_d)!=0;case 17:return!!ky(this);case 18:return(this.Bb&eu)!=0;case 19:return a=Ro(this),!!a&&(a.Bb&eu)!=0;case 20:return(this.Bb&Io)==0;case 21:return!!this.b;case 22:return!!_ut(this);case 23:return!!this.a&&this.a.i!=0}return nf(this,t-yr((Tn(),o7)),Mn((n=l(Kn(this,16),29),n||o7),t))},h.bi=function(t,n){var r,a;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:poe(this,ei(n));return;case 2:c2(this,Rt(Bt(n)));return;case 3:u2(this,Rt(Bt(n)));return;case 4:i2(this,l(n,17).a);return;case 5:My(this,l(n,17).a);return;case 8:Gm(this,l(n,142));return;case 9:a=$1(this,l(n,89),null),a&&a.oj();return;case 10:AE(this,Rt(Bt(n)));return;case 11:DE(this,Rt(Bt(n)));return;case 12:LE(this,Rt(Bt(n)));return;case 13:Z3e(this,ei(n));return;case 15:ME(this,Rt(Bt(n)));return;case 16:IE(this,Rt(Bt(n)));return;case 18:L2n(this,Rt(Bt(n)));return;case 20:v8e(this,Rt(Bt(n)));return;case 21:b7e(this,l(n,19));return;case 23:!this.a&&(this.a=new $5(D4,this,23)),$r(this.a),!this.a&&(this.a=new $5(D4,this,23)),As(this.a,l(n,16));return}uf(this,t-yr((Tn(),o7)),Mn((r=l(Kn(this,16),29),r||o7),t),n)},h.ii=function(){return Tn(),o7},h.ki=function(t){var n,r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:De(this.Cb,90)&&zy(Yl(l(this.Cb,90)),4),Fu(this,null);return;case 2:c2(this,!0);return;case 3:u2(this,!0);return;case 4:i2(this,0);return;case 5:My(this,1);return;case 8:Gm(this,null);return;case 9:r=$1(this,null,null),r&&r.oj();return;case 10:AE(this,!0);return;case 11:DE(this,!1);return;case 12:LE(this,!1);return;case 13:this.i=null,xV(this,null);return;case 15:ME(this,!1);return;case 16:IE(this,!1);return;case 18:m8e(this,!1),De(this.Cb,90)&&zy(Yl(l(this.Cb,90)),2);return;case 20:v8e(this,!0);return;case 21:b7e(this,null);return;case 23:!this.a&&(this.a=new $5(D4,this,23)),$r(this.a);return}cf(this,t-yr((Tn(),o7)),Mn((n=l(Kn(this,16),29),n||o7),t))},h.pi=function(){$7e(this),Wk(ic((El(),io),this)),Of(this),this.Bb|=1},h.uk=function(){return Ro(this)},h._k=function(){var t;return t=Ro(this),!!t&&(t.Bb&eu)!=0},h.al=function(){return(this.Bb&eu)!=0},h.bl=function(){return(this.Bb&Io)!=0},h.Yk=function(t,n){return this.c=null,o8e(this,t,n)},h.Ib=function(){var t;return this.Db&64?BU(this):(t=new Af(BU(this)),t.a+=" (containment: ",Gp(t,(this.Bb&eu)!=0),t.a+=", resolveProxies: ",Gp(t,(this.Bb&Io)!=0),t.a+=")",t.a)},I(Gn,"EReferenceImpl",102),D(561,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,561:1,119:1,120:1},OS),h.Fb=function(t){return this===t},h.ld=function(){return this.b},h.md=function(){return this.c},h.Hb=function(){return fw(this)},h.Di=function(t){Ndn(this,ei(t))},h.nd=function(t){return wdn(this,ei(t))},h.Lh=function(t,n,r){var a;switch(t){case 0:return this.b;case 1:return this.c}return sf(this,t-yr((Tn(),No)),Mn((a=l(Kn(this,16),29),a||No),t),n,r)},h.Wh=function(t){var n;switch(t){case 0:return this.b!=null;case 1:return this.c!=null}return nf(this,t-yr((Tn(),No)),Mn((n=l(Kn(this,16),29),n||No),t))},h.bi=function(t,n){var r;switch(t){case 0:Pdn(this,ei(n));return;case 1:d7e(this,ei(n));return}uf(this,t-yr((Tn(),No)),Mn((r=l(Kn(this,16),29),r||No),t),n)},h.ii=function(){return Tn(),No},h.ki=function(t){var n;switch(t){case 0:f7e(this,null);return;case 1:d7e(this,null);return}cf(this,t-yr((Tn(),No)),Mn((n=l(Kn(this,16),29),n||No),t))},h.Bi=function(){var t;return this.a==-1&&(t=this.b,this.a=t==null?0:s2(t)),this.a},h.Ci=function(t){this.a=t},h.Ib=function(){var t;return this.Db&64?g0(this):(t=new Af(g0(this)),t.a+=" (key: ",Xo(t,this.b),t.a+=", value: ",Xo(t,this.c),t.a+=")",t.a)},h.a=-1,h.b=null,h.c=null;var Yc=I(Gn,"EStringToStringMapEntryImpl",561),Q_t=ks(us,"FeatureMap/Entry/Internal");D(576,1,YG),h.xl=function(t){return this.yl(l(t,54))},h.yl=function(t){return this.xl(t)},h.Fb=function(t){var n,r;return this===t?!0:De(t,76)?(n=l(t,76),n.Lk()==this.c?(r=this.md(),r==null?n.md()==null:Pi(r,n.md())):!1):!1},h.Lk=function(){return this.c},h.Hb=function(){var t;return t=this.md(),es(this.c)^(t==null?0:es(t))},h.Ib=function(){var t,n;return t=this.c,n=Ah(t.qk()).yi(),t.xe(),(n!=null&&n.length!=0?n+":"+t.xe():t.xe())+"="+this.md()},I(Gn,"EStructuralFeatureImpl/BasicFeatureMapEntry",576),D(791,576,YG,Jye),h.yl=function(t){return new Jye(this.c,t)},h.md=function(){return this.a},h.zl=function(t,n,r){return v3n(this,t,this.a,n,r)},h.Al=function(t,n,r){return w3n(this,t,this.a,n,r)},I(Gn,"EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry",791),D(1350,1,{},Ntt),h.yk=function(t,n,r,a,o){var f;return f=l(tE(t,this.b),220),f.Yl(this.a).Fk(a)},h.zk=function(t,n,r,a,o){var f;return f=l(tE(t,this.b),220),f.Pl(this.a,a,o)},h.Ak=function(t,n,r,a,o){var f;return f=l(tE(t,this.b),220),f.Ql(this.a,a,o)},h.Bk=function(t,n,r){var a;return a=l(tE(t,this.b),220),a.Yl(this.a).Qj()},h.Ck=function(t,n,r,a){var o;o=l(tE(t,this.b),220),o.Yl(this.a).Wb(a)},h.Dk=function(t,n,r){return l(tE(t,this.b),220).Yl(this.a)},h.Ek=function(t,n,r){var a;a=l(tE(t,this.b),220),a.Yl(this.a).Gk()},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator",1350),D(91,1,{},Xp,Om,Jp,Rm),h.yk=function(t,n,r,a,o){var f;if(f=n.li(r),f==null&&n.mi(r,f=WU(this,t)),!o)switch(this.e){case 50:case 41:return l(f,597).bk();case 40:return l(f,220).Vl()}return f},h.zk=function(t,n,r,a,o){var f,g;return g=n.li(r),g==null&&n.mi(r,g=WU(this,t)),f=l(g,71).Wk(a,o),f},h.Ak=function(t,n,r,a,o){var f;return f=n.li(r),f!=null&&(o=l(f,71).Xk(a,o)),o},h.Bk=function(t,n,r){var a;return a=n.li(r),a!=null&&l(a,79).Qj()},h.Ck=function(t,n,r,a){var o;o=l(n.li(r),79),!o&&n.mi(r,o=WU(this,t)),o.Wb(a)},h.Dk=function(t,n,r){var a,o;return o=n.li(r),o==null&&n.mi(r,o=WU(this,t)),De(o,79)?l(o,79):(a=l(n.li(r),15),new xQe(a))},h.Ek=function(t,n,r){var a;a=l(n.li(r),79),!a&&n.mi(r,a=WU(this,t)),a.Gk()},h.b=0,h.e=0,I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateMany",91),D(512,1,{}),h.zk=function(t,n,r,a,o){throw ue(new Qr)},h.Ak=function(t,n,r,a,o){throw ue(new Qr)},h.Dk=function(t,n,r){return new Iat(this,t,n,r)};var Sg;I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingle",512),D(1367,1,i0e,Iat),h.Fk=function(t){return this.a.yk(this.c,this.d,this.b,t,!0)},h.Qj=function(){return this.a.Bk(this.c,this.d,this.b)},h.Wb=function(t){this.a.Ck(this.c,this.d,this.b,t)},h.Gk=function(){this.a.Ek(this.c,this.d,this.b)},h.b=0,I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingle/1",1367),D(784,512,{},$5e),h.yk=function(t,n,r,a,o){return sle(t,t.Ph(),t.Fh())==this.b?this.bl()&&a?Uue(t):t.Ph():null},h.zk=function(t,n,r,a,o){var f,g;return t.Ph()&&(o=(f=t.Fh(),f>=0?t.Ah(o):t.Ph().Th(t,-1-f,null,o))),g=ms(t.Dh(),this.e),t.Ch(a,g,o)},h.Ak=function(t,n,r,a,o){var f;return f=ms(t.Dh(),this.e),t.Ch(null,f,o)},h.Bk=function(t,n,r){var a;return a=ms(t.Dh(),this.e),!!t.Ph()&&t.Fh()==a},h.Ck=function(t,n,r,a){var o,f,g,w,E;if(a!=null&&!ule(this.a,a))throw ue(new kk(XG+(De(a,58)?_xe(l(a,58).Dh()):K6e(bh(a)))+QG+this.a+"'"));if(o=t.Ph(),g=ms(t.Dh(),this.e),qe(a)!==qe(o)||t.Fh()!=g&&a!=null){if(FE(t,l(a,58)))throw ue(new Yn(EL+t.Ib()));E=null,o&&(E=(f=t.Fh(),f>=0?t.Ah(E):t.Ph().Th(t,-1-f,null,E))),w=l(a,54),w&&(E=w.Rh(t,ms(w.Dh(),this.b),null,E)),E=t.Ch(w,g,E),E&&E.oj()}else t.vh()&&t.wh()&&Ni(t,new _a(t,1,g,a,a))},h.Ek=function(t,n,r){var a,o,f,g;a=t.Ph(),a?(g=(o=t.Fh(),o>=0?t.Ah(null):t.Ph().Th(t,-1-o,null,null)),f=ms(t.Dh(),this.e),g=t.Ch(null,f,g),g&&g.oj()):t.vh()&&t.wh()&&Ni(t,new X_(t,1,this.e,null,null))},h.bl=function(){return!1},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainer",784),D(1351,784,{},kit),h.bl=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving",1351),D(574,512,{}),h.yk=function(t,n,r,a,o){var f;return f=n.li(r),f==null?this.b:qe(f)===qe(Sg)?null:f},h.Bk=function(t,n,r){var a;return a=n.li(r),a!=null&&(qe(a)===qe(Sg)||!Pi(a,this.b))},h.Ck=function(t,n,r,a){var o,f;t.vh()&&t.wh()?(o=(f=n.li(r),f==null?this.b:qe(f)===qe(Sg)?null:f),a==null?this.c!=null?(n.mi(r,null),a=this.b):this.b!=null?n.mi(r,Sg):n.mi(r,null):(this.Bl(a),n.mi(r,a)),Ni(t,this.d.Cl(t,1,this.e,o,a))):a==null?this.c!=null?n.mi(r,null):this.b!=null?n.mi(r,Sg):n.mi(r,null):(this.Bl(a),n.mi(r,a))},h.Ek=function(t,n,r){var a,o;t.vh()&&t.wh()?(a=(o=n.li(r),o==null?this.b:qe(o)===qe(Sg)?null:o),n.ni(r),Ni(t,this.d.Cl(t,1,this.e,a,this.b))):n.ni(r)},h.Bl=function(t){throw ue(new IQe)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData",574),D(_6,1,{},NS),h.Cl=function(t,n,r,a,o){return new X_(t,n,r,a,o)},h.Dl=function(t,n,r,a,o,f){return new roe(t,n,r,a,o,f)};var MPe,DPe,IPe,OPe,NPe,PPe,BPe,ipe,FPe;I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator",_6),D(1368,_6,{},H0),h.Cl=function(t,n,r,a,o){return new m6e(t,n,r,Rt(Bt(a)),Rt(Bt(o)))},h.Dl=function(t,n,r,a,o,f){return new rct(t,n,r,Rt(Bt(a)),Rt(Bt(o)),f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1",1368),D(1369,_6,{},AI),h.Cl=function(t,n,r,a,o){return new Q6e(t,n,r,l(a,222).a,l(o,222).a)},h.Dl=function(t,n,r,a,o,f){return new Xot(t,n,r,l(a,222).a,l(o,222).a,f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2",1369),D(1370,_6,{},LI),h.Cl=function(t,n,r,a,o){return new J6e(t,n,r,l(a,180).a,l(o,180).a)},h.Dl=function(t,n,r,a,o,f){return new Qot(t,n,r,l(a,180).a,l(o,180).a,f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3",1370),D(1371,_6,{},f8),h.Cl=function(t,n,r,a,o){return new p6e(t,n,r,ze(Ge(a)),ze(Ge(o)))},h.Dl=function(t,n,r,a,o,f){return new Jot(t,n,r,ze(Ge(a)),ze(Ge(o)),f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4",1371),D(1372,_6,{},tre),h.Cl=function(t,n,r,a,o){return new t7e(t,n,r,l(a,161).a,l(o,161).a)},h.Dl=function(t,n,r,a,o,f){return new Zot(t,n,r,l(a,161).a,l(o,161).a,f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5",1372),D(1373,_6,{},nre),h.Cl=function(t,n,r,a,o){return new b6e(t,n,r,l(a,17).a,l(o,17).a)},h.Dl=function(t,n,r,a,o,f){return new ect(t,n,r,l(a,17).a,l(o,17).a,f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6",1373),D(1374,_6,{},rre),h.Cl=function(t,n,r,a,o){return new Z6e(t,n,r,l(a,168).a,l(o,168).a)},h.Dl=function(t,n,r,a,o,f){return new tct(t,n,r,l(a,168).a,l(o,168).a,f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7",1374),D(1375,_6,{},ire),h.Cl=function(t,n,r,a,o){return new e7e(t,n,r,l(a,191).a,l(o,191).a)},h.Dl=function(t,n,r,a,o,f){return new nct(t,n,r,l(a,191).a,l(o,191).a,f)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8",1375),D(1353,574,{},Oat),h.Bl=function(t){if(!this.a.fk(t))throw ue(new kk(XG+bh(t)+QG+this.a+"'"))},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic",1353),D(1354,574,{},yst),h.Bl=function(t){},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic",1354),D(785,574,{}),h.Bk=function(t,n,r){var a;return a=n.li(r),a!=null},h.Ck=function(t,n,r,a){var o,f;t.vh()&&t.wh()?(o=!0,f=n.li(r),f==null?(o=!1,f=this.b):qe(f)===qe(Sg)&&(f=null),a==null?this.c!=null?(n.mi(r,null),a=this.b):n.mi(r,Sg):(this.Bl(a),n.mi(r,a)),Ni(t,this.d.Dl(t,1,this.e,f,a,!o))):a==null?this.c!=null?n.mi(r,null):n.mi(r,Sg):(this.Bl(a),n.mi(r,a))},h.Ek=function(t,n,r){var a,o;t.vh()&&t.wh()?(a=!0,o=n.li(r),o==null?(a=!1,o=this.b):qe(o)===qe(Sg)&&(o=null),n.ni(r),Ni(t,this.d.Dl(t,2,this.e,o,this.b,a))):n.ni(r)},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable",785),D(1355,785,{},Nat),h.Bl=function(t){if(!this.a.fk(t))throw ue(new kk(XG+bh(t)+QG+this.a+"'"))},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic",1355),D(1356,785,{},xst),h.Bl=function(t){},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic",1356),D(410,512,{},cH),h.yk=function(t,n,r,a,o){var f,g,w,E,C;if(C=n.li(r),this.tk()&&qe(C)===qe(Sg))return null;if(this.bl()&&a&&C!=null){if(w=l(C,54),w.Vh()&&(E=yb(t,w),w!=E)){if(!ule(this.a,E))throw ue(new kk(XG+bh(E)+QG+this.a+"'"));n.mi(r,C=E),this.al()&&(f=l(E,54),g=w.Th(t,this.b?ms(w.Dh(),this.b):-1-ms(t.Dh(),this.e),null,null),!f.Ph()&&(g=f.Rh(t,this.b?ms(f.Dh(),this.b):-1-ms(t.Dh(),this.e),null,g)),g&&g.oj()),t.vh()&&t.wh()&&Ni(t,new X_(t,9,this.e,w,E))}return C}else return C},h.zk=function(t,n,r,a,o){var f,g;return g=n.li(r),qe(g)===qe(Sg)&&(g=null),n.mi(r,a),this.Mj()?qe(g)!==qe(a)&&g!=null&&(f=l(g,54),o=f.Th(t,ms(f.Dh(),this.b),null,o)):this.al()&&g!=null&&(o=l(g,54).Th(t,-1-ms(t.Dh(),this.e),null,o)),t.vh()&&t.wh()&&(!o&&(o=new nb(4)),o.nj(new X_(t,1,this.e,g,a))),o},h.Ak=function(t,n,r,a,o){var f;return f=n.li(r),qe(f)===qe(Sg)&&(f=null),n.ni(r),t.vh()&&t.wh()&&(!o&&(o=new nb(4)),this.tk()?o.nj(new X_(t,2,this.e,f,null)):o.nj(new X_(t,1,this.e,f,null))),o},h.Bk=function(t,n,r){var a;return a=n.li(r),a!=null},h.Ck=function(t,n,r,a){var o,f,g,w,E;if(a!=null&&!ule(this.a,a))throw ue(new kk(XG+(De(a,58)?_xe(l(a,58).Dh()):K6e(bh(a)))+QG+this.a+"'"));E=n.li(r),w=E!=null,this.tk()&&qe(E)===qe(Sg)&&(E=null),g=null,this.Mj()?qe(E)!==qe(a)&&(E!=null&&(o=l(E,54),g=o.Th(t,ms(o.Dh(),this.b),null,g)),a!=null&&(o=l(a,54),g=o.Rh(t,ms(o.Dh(),this.b),null,g))):this.al()&&qe(E)!==qe(a)&&(E!=null&&(g=l(E,54).Th(t,-1-ms(t.Dh(),this.e),null,g)),a!=null&&(g=l(a,54).Rh(t,-1-ms(t.Dh(),this.e),null,g))),a==null&&this.tk()?n.mi(r,Sg):n.mi(r,a),t.vh()&&t.wh()?(f=new roe(t,1,this.e,E,a,this.tk()&&!w),g?(g.nj(f),g.oj()):Ni(t,f)):g&&g.oj()},h.Ek=function(t,n,r){var a,o,f,g,w;w=n.li(r),g=w!=null,this.tk()&&qe(w)===qe(Sg)&&(w=null),f=null,w!=null&&(this.Mj()?(a=l(w,54),f=a.Th(t,ms(a.Dh(),this.b),null,f)):this.al()&&(f=l(w,54).Th(t,-1-ms(t.Dh(),this.e),null,f))),n.ni(r),t.vh()&&t.wh()?(o=new roe(t,this.tk()?2:1,this.e,w,null,g),f?(f.nj(o),f.oj()):Ni(t,o)):f&&f.oj()},h.Mj=function(){return!1},h.al=function(){return!1},h.bl=function(){return!1},h.tk=function(){return!1},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObject",410),D(575,410,{},oae),h.al=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment",575),D(1359,575,{},wrt),h.bl=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving",1359),D(787,575,{},jye),h.tk=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable",787),D(1361,787,{},yrt),h.bl=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving",1361),D(650,575,{},yae),h.Mj=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse",650),D(1360,650,{},Eit),h.bl=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving",1360),D(788,650,{},C4e),h.tk=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable",788),D(1362,788,{},Tit),h.bl=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving",1362),D(651,410,{},$ye),h.bl=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving",651),D(1363,651,{},xrt),h.tk=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable",1363),D(789,651,{},E4e),h.Mj=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse",789),D(1364,789,{},Cit),h.tk=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable",1364),D(1357,410,{},krt),h.tk=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable",1357),D(786,410,{},T4e),h.Mj=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse",786),D(1358,786,{},Sit),h.tk=function(){return!0},I(Gn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable",1358),D(790,576,YG,x5e),h.yl=function(t){return new x5e(this.a,this.c,t)},h.md=function(){return this.b},h.zl=function(t,n,r){return bvn(this,t,this.b,r)},h.Al=function(t,n,r){return mvn(this,t,this.b,r)},I(Gn,"EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry",790),D(1365,1,i0e,xQe),h.Fk=function(t){return this.a},h.Qj=function(){return De(this.a,97)?l(this.a,97).Qj():!this.a.dc()},h.Wb=function(t){this.a.$b(),this.a.Gc(l(t,15))},h.Gk=function(){De(this.a,97)?l(this.a,97).Gk():this.a.$b()},I(Gn,"EStructuralFeatureImpl/SettingMany",1365),D(1366,576,YG,Wct),h.xl=function(t){return new lae((Gi(),UM),this.b.ri(this.a,t))},h.md=function(){return null},h.zl=function(t,n,r){return r},h.Al=function(t,n,r){return r},I(Gn,"EStructuralFeatureImpl/SimpleContentFeatureMapEntry",1366),D(652,576,YG,lae),h.xl=function(t){return new lae(this.c,t)},h.md=function(){return this.a},h.zl=function(t,n,r){return r},h.Al=function(t,n,r){return r},I(Gn,"EStructuralFeatureImpl/SimpleFeatureMapEntry",652),D(403,506,Bd,Xd),h.aj=function(t){return We(Vf,Rn,29,t,0,1)},h.Yi=function(){return!1},I(Gn,"ESuperAdapter/1",403),D(457,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,850:1,54:1,99:1,158:1,457:1,119:1,120:1},PS),h.Lh=function(t,n,r){var a;switch(t){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),this.Ab;case 1:return this.zb;case 2:return!this.a&&(this.a=new G_(this,Wo,this)),this.a}return sf(this,t-yr((Tn(),T3)),Mn((a=l(Kn(this,16),29),a||T3),t),n,r)},h.Uh=function(t,n,r){var a,o;switch(n){case 0:return!this.Ab&&(this.Ab=new nt(mi,this,0,3)),To(this.Ab,t,r);case 2:return!this.a&&(this.a=new G_(this,Wo,this)),To(this.a,t,r)}return o=l(Mn((a=l(Kn(this,16),29),a||(Tn(),T3)),n),69),o.wk().Ak(this,Ku(this),n-yr((Tn(),T3)),t,r)},h.Wh=function(t){var n;switch(t){case 0:return!!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return!!this.a&&this.a.i!=0}return nf(this,t-yr((Tn(),T3)),Mn((n=l(Kn(this,16),29),n||T3),t))},h.bi=function(t,n){var r;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab),!this.Ab&&(this.Ab=new nt(mi,this,0,3)),As(this.Ab,l(n,16));return;case 1:Fu(this,ei(n));return;case 2:!this.a&&(this.a=new G_(this,Wo,this)),$r(this.a),!this.a&&(this.a=new G_(this,Wo,this)),As(this.a,l(n,16));return}uf(this,t-yr((Tn(),T3)),Mn((r=l(Kn(this,16),29),r||T3),t),n)},h.ii=function(){return Tn(),T3},h.ki=function(t){var n;switch(t){case 0:!this.Ab&&(this.Ab=new nt(mi,this,0,3)),$r(this.Ab);return;case 1:Fu(this,null);return;case 2:!this.a&&(this.a=new G_(this,Wo,this)),$r(this.a);return}cf(this,t-yr((Tn(),T3)),Mn((n=l(Kn(this,16),29),n||T3),t))},I(Gn,"ETypeParameterImpl",457),D(458,83,kc,G_),h.Nj=function(t,n){return Dxn(this,l(t,89),n)},h.Oj=function(t,n){return Ixn(this,l(t,89),n)},I(Gn,"ETypeParameterImpl/1",458),D(647,45,m6,Vie),h.ec=function(){return new Pz(this)},I(Gn,"ETypeParameterImpl/2",647),D(570,q1,Tl,Pz),h.Fc=function(t){return Wrt(this,l(t,89))},h.Gc=function(t){var n,r,a;for(a=!1,r=t.Kc();r.Ob();)n=l(r.Pb(),89),ki(this.a,n,"")==null&&(a=!0);return a},h.$b=function(){Nl(this.a)},h.Hc=function(t){return Hu(this.a,t)},h.Kc=function(){var t;return t=new qm(new Sr(this.a).a),new Bz(t)},h.Mc=function(t){return Rut(this,t)},h.gc=function(){return d_(this.a)},I(Gn,"ETypeParameterImpl/2/1",570),D(571,1,Oa,Bz),h.Nb=function(t){Za(this,t)},h.Pb=function(){return l(Nw(this.a).ld(),89)},h.Ob=function(){return this.a.b},h.Qb=function(){Klt(this.a)},I(Gn,"ETypeParameterImpl/2/1/1",571),D(1329,45,m6,hJe),h._b=function(t){return Ia(t)?soe(this,t):!!zo(this.f,t)},h.xc=function(t){var n,r;return n=Ia(t)?xu(this,t):hc(zo(this.f,t)),De(n,851)?(r=l(n,851),n=r.Kk(),ki(this,l(t,241),n),n):n??(t==null?(use(),Z_t):null)},I(Gn,"EValidatorRegistryImpl",1329),D(1349,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,2040:1,54:1,99:1,158:1,119:1,120:1},d8),h.ri=function(t,n){switch(t.hk()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return n==null?null:xc(n);case 25:return Awn(n);case 27:return qvn(n);case 28:return Hvn(n);case 29:return n==null?null:Cnt(jM[0],l(n,206));case 41:return n==null?"":_m(l(n,297));case 42:return xc(n);case 50:return ei(n);default:throw ue(new Yn(yT+t.xe()+t3))}},h.si=function(t){var n,r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe;switch(t.G==-1&&(t.G=(z=Ah(t),z?f2(z.vi(),t):-1)),t.G){case 0:return r=new zie,r;case 1:return n=new CI,n;case 2:return a=new hz,a;case 4:return o=new Fz,o;case 5:return f=new lJe,f;case 6:return g=new PQe,g;case 7:return w=new fz,w;case 10:return C=new m5,C;case 11:return L=new qie,L;case 12:return B=new qat,B;case 13:return V=new Hie,V;case 14:return J=new Hye,J;case 17:return te=new OS,te;case 18:return E=new Qv,E;case 19:return fe=new PS,fe;default:throw ue(new Yn(qfe+t.zb+t3))}},h.ti=function(t,n){switch(t.hk()){case 20:return n==null?null:new h3e(n);case 21:return n==null?null:new ob(n);case 23:case 22:return n==null?null:z5n(n);case 26:case 24:return n==null?null:fN(Oh(n,-128,127)<<24>>24);case 25:return aTn(n);case 27:return A7n(n);case 28:return L7n(n);case 29:return Jxn(n);case 32:case 31:return n==null?null:jy(n);case 38:case 37:return n==null?null:new Awe(n);case 40:case 39:return n==null?null:pt(Oh(n,lo,Ii));case 41:return null;case 42:return n==null,null;case 44:case 43:return n==null?null:ap(KU(n));case 49:case 48:return n==null?null:_E(Oh(n,JG,32767)<<16>>16);case 50:return n;default:throw ue(new Yn(yT+t.xe()+t3))}},I(Gn,"EcoreFactoryImpl",1349),D(560,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,2038:1,54:1,99:1,158:1,184:1,560:1,119:1,120:1,690:1},fat),h.gb=!1,h.hb=!1;var RPe,J_t=!1;I(Gn,"EcorePackageImpl",560),D(1234,1,{851:1},k1),h.Kk=function(){return Rnt(),eAt},I(Gn,"EcorePackageImpl/1",1234),D(1243,1,yi,A$),h.fk=function(t){return De(t,155)},h.gk=function(t){return We(uF,Rn,155,t,0,1)},I(Gn,"EcorePackageImpl/10",1243),D(1244,1,yi,L$),h.fk=function(t){return De(t,197)},h.gk=function(t){return We(Yge,Rn,197,t,0,1)},I(Gn,"EcorePackageImpl/11",1244),D(1245,1,yi,M$),h.fk=function(t){return De(t,58)},h.gk=function(t){return We(Xb,Rn,58,t,0,1)},I(Gn,"EcorePackageImpl/12",1245),D(1246,1,yi,D$),h.fk=function(t){return De(t,411)},h.gk=function(t){return We(Uf,LSe,62,t,0,1)},I(Gn,"EcorePackageImpl/13",1246),D(1247,1,yi,I$),h.fk=function(t){return De(t,241)},h.gk=function(t){return We(u1,Rn,241,t,0,1)},I(Gn,"EcorePackageImpl/14",1247),D(1248,1,yi,O$),h.fk=function(t){return De(t,518)},h.gk=function(t){return We(k3,Rn,2116,t,0,1)},I(Gn,"EcorePackageImpl/15",1248),D(1249,1,yi,V0),h.fk=function(t){return De(t,102)},h.gk=function(t){return We(I4,S6,19,t,0,1)},I(Gn,"EcorePackageImpl/16",1249),D(1250,1,yi,nl),h.fk=function(t){return De(t,179)},h.gk=function(t){return We(dl,S6,179,t,0,1)},I(Gn,"EcorePackageImpl/17",1250),D(1251,1,yi,sre),h.fk=function(t){return De(t,481)},h.gk=function(t){return We(M4,Rn,481,t,0,1)},I(Gn,"EcorePackageImpl/18",1251),D(1252,1,yi,are),h.fk=function(t){return De(t,561)},h.gk=function(t){return We(Yc,e5t,561,t,0,1)},I(Gn,"EcorePackageImpl/19",1252),D(1235,1,yi,ore),h.fk=function(t){return De(t,331)},h.gk=function(t){return We(D4,S6,35,t,0,1)},I(Gn,"EcorePackageImpl/2",1235),D(1253,1,yi,rl),h.fk=function(t){return De(t,248)},h.gk=function(t){return We(Wo,m5t,89,t,0,1)},I(Gn,"EcorePackageImpl/20",1253),D(1254,1,yi,BS),h.fk=function(t){return De(t,457)},h.gk=function(t){return We(Zu,Rn,850,t,0,1)},I(Gn,"EcorePackageImpl/21",1254),D(1255,1,yi,N$),h.fk=function(t){return hy(t)},h.gk=function(t){return We(Ns,dt,485,t,8,1)},I(Gn,"EcorePackageImpl/22",1255),D(1256,1,yi,P$),h.fk=function(t){return De(t,195)},h.gk=function(t){return We(Al,dt,195,t,0,2)},I(Gn,"EcorePackageImpl/23",1256),D(1257,1,yi,g8),h.fk=function(t){return De(t,222)},h.gk=function(t){return We(jx,dt,222,t,0,1)},I(Gn,"EcorePackageImpl/24",1257),D(1258,1,yi,cre),h.fk=function(t){return De(t,180)},h.gk=function(t){return We(PL,dt,180,t,0,1)},I(Gn,"EcorePackageImpl/25",1258),D(1259,1,yi,ak),h.fk=function(t){return De(t,206)},h.gk=function(t){return We(cK,dt,206,t,0,1)},I(Gn,"EcorePackageImpl/26",1259),D(1260,1,yi,ure),h.fk=function(t){return!1},h.gk=function(t){return We(nBe,Rn,2215,t,0,1)},I(Gn,"EcorePackageImpl/27",1260),D(1261,1,yi,B$),h.fk=function(t){return fy(t)},h.gk=function(t){return We(ta,dt,345,t,7,1)},I(Gn,"EcorePackageImpl/28",1261),D(1262,1,yi,lre),h.fk=function(t){return De(t,61)},h.gk=function(t){return We(mPe,Qy,61,t,0,1)},I(Gn,"EcorePackageImpl/29",1262),D(1236,1,yi,hre),h.fk=function(t){return De(t,519)},h.gk=function(t){return We(mi,{3:1,4:1,5:1,2033:1},598,t,0,1)},I(Gn,"EcorePackageImpl/3",1236),D(1263,1,yi,FS),h.fk=function(t){return De(t,582)},h.gk=function(t){return We(yPe,Rn,2039,t,0,1)},I(Gn,"EcorePackageImpl/30",1263),D(1264,1,yi,F$),h.fk=function(t){return De(t,160)},h.gk=function(t){return We(HPe,Qy,160,t,0,1)},I(Gn,"EcorePackageImpl/31",1264),D(1265,1,yi,MI),h.fk=function(t){return De(t,76)},h.gk=function(t){return We(CY,S5t,76,t,0,1)},I(Gn,"EcorePackageImpl/32",1265),D(1266,1,yi,RS),h.fk=function(t){return De(t,161)},h.gk=function(t){return We(_T,dt,161,t,0,1)},I(Gn,"EcorePackageImpl/33",1266),D(1267,1,yi,fre),h.fk=function(t){return De(t,17)},h.gk=function(t){return We(ro,dt,17,t,0,1)},I(Gn,"EcorePackageImpl/34",1267),D(1268,1,yi,dre),h.fk=function(t){return De(t,297)},h.gk=function(t){return We(qSe,Rn,297,t,0,1)},I(Gn,"EcorePackageImpl/35",1268),D(1269,1,yi,DI),h.fk=function(t){return De(t,168)},h.gk=function(t){return We(r3,dt,168,t,0,1)},I(Gn,"EcorePackageImpl/36",1269),D(1270,1,yi,jS),h.fk=function(t){return De(t,85)},h.gk=function(t){return We(HSe,Rn,85,t,0,1)},I(Gn,"EcorePackageImpl/37",1270),D(1271,1,yi,E1),h.fk=function(t){return De(t,599)},h.gk=function(t){return We(jPe,Rn,599,t,0,1)},I(Gn,"EcorePackageImpl/38",1271),D(1272,1,yi,ok),h.fk=function(t){return!1},h.gk=function(t){return We(rBe,Rn,2216,t,0,1)},I(Gn,"EcorePackageImpl/39",1272),D(1237,1,yi,gre),h.fk=function(t){return De(t,90)},h.gk=function(t){return We(Vf,Rn,29,t,0,1)},I(Gn,"EcorePackageImpl/4",1237),D(1273,1,yi,ck),h.fk=function(t){return De(t,191)},h.gk=function(t){return We(i3,dt,191,t,0,1)},I(Gn,"EcorePackageImpl/40",1273),D(1274,1,yi,II),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(Gn,"EcorePackageImpl/41",1274),D(1275,1,yi,xm),h.fk=function(t){return De(t,596)},h.gk=function(t){return We(wPe,Rn,596,t,0,1)},I(Gn,"EcorePackageImpl/42",1275),D(1276,1,yi,$S),h.fk=function(t){return!1},h.gk=function(t){return We(iBe,dt,2217,t,0,1)},I(Gn,"EcorePackageImpl/43",1276),D(1277,1,yi,OI),h.fk=function(t){return De(t,44)},h.gk=function(t){return We(uv,XU,44,t,0,1)},I(Gn,"EcorePackageImpl/44",1277),D(1238,1,yi,U0),h.fk=function(t){return De(t,142)},h.gk=function(t){return We(l1,Rn,142,t,0,1)},I(Gn,"EcorePackageImpl/5",1238),D(1239,1,yi,zS),h.fk=function(t){return De(t,156)},h.gk=function(t){return We(tpe,Rn,156,t,0,1)},I(Gn,"EcorePackageImpl/6",1239),D(1240,1,yi,T1),h.fk=function(t){return De(t,469)},h.gk=function(t){return We(TY,Rn,685,t,0,1)},I(Gn,"EcorePackageImpl/7",1240),D(1241,1,yi,C1),h.fk=function(t){return De(t,582)},h.gk=function(t){return We(wp,Rn,694,t,0,1)},I(Gn,"EcorePackageImpl/8",1241),D(1242,1,yi,pre),h.fk=function(t){return De(t,480)},h.gk=function(t){return We(RM,Rn,480,t,0,1)},I(Gn,"EcorePackageImpl/9",1242),D(1038,2080,Z4t,IJe),h.Mi=function(t,n){b4n(this,l(n,424))},h.Qi=function(t,n){Apt(this,t,l(n,424))},I(Gn,"MinimalEObjectImpl/1ArrayDelegatingAdapterList",1038),D(1039,152,YP,nat),h.jj=function(){return this.a.a},I(Gn,"MinimalEObjectImpl/1ArrayDelegatingAdapterList/1",1039),D(1067,1066,{},bnt),I("org.eclipse.emf.ecore.plugin","EcorePlugin",1067);var jPe=ks(_5t,"Resource");D(799,1524,A5t),h.Hl=function(t){},h.Il=function(t){},h.El=function(){return!this.a&&(this.a=new Pie(this)),this.a},h.Fl=function(t){var n,r,a,o,f;if(a=t.length,a>0)if(Xn(0,t.length),t.charCodeAt(0)==47){for(f=new Bu(4),o=1,n=1;n0&&(t=(Ga(0,r,t.length),t.substr(0,r))));return Ukn(this,t)},h.Gl=function(){return this.c},h.Ib=function(){var t;return _m(this.Rm)+"@"+(t=es(this)>>>0,t.toString(16))+" uri='"+this.d+"'"},h.b=!1,I(s0e,"ResourceImpl",799),D(1525,799,A5t,kQe),I(s0e,"BinaryResourceImpl",1525),D(1190,708,Zfe),h.bj=function(t){return De(t,58)?Bpn(this,l(t,58)):De(t,599)?new or(l(t,599).El()):qe(t)===qe(this.f)?l(t,16).Kc():(Fk(),fF.a)},h.Ob=function(){return x9e(this)},h.a=!1,I(us,"EcoreUtil/ContentTreeIterator",1190),D(1526,1190,Zfe,Ist),h.bj=function(t){return qe(t)===qe(this.f)?l(t,15).Kc():new Lct(l(t,58))},I(s0e,"ResourceImpl/5",1526),D(658,2092,b5t,Pie),h.Hc=function(t){return this.i<=4?jE(this,t):De(t,54)&&l(t,54).Jh()==this.a},h.Mi=function(t,n){t==this.i-1&&(this.a.b||(this.a.b=!0))},h.Oi=function(t,n){t==0?this.a.b||(this.a.b=!0):Noe(this,t,n)},h.Qi=function(t,n){},h.Ri=function(t,n,r){},h.Lj=function(){return 2},h.jj=function(){return this.a},h.Mj=function(){return!0},h.Nj=function(t,n){var r;return r=l(t,54),n=r.fi(this.a,n),n},h.Oj=function(t,n){var r;return r=l(t,54),r.fi(null,n)},h.Pj=function(){return!1},h.Si=function(){return!0},h.aj=function(t){return We(Xb,Rn,58,t,0,1)},h.Yi=function(){return!1},I(s0e,"ResourceImpl/ContentsEList",658),D(970,2062,iT,EQe),h.fd=function(t){return this.a.Ki(t)},h.gc=function(){return this.a.gc()},I(us,"AbstractSequentialInternalEList/1",970);var $Pe,zPe,io,qPe;D(634,1,{},Nit);var SY,_Y;I(us,"BasicExtendedMetaData",634),D(1181,1,{},Btt),h.Jl=function(){return null},h.Kl=function(){return this.a==-2&&Ye(this,Uxn(this.d,this.b)),this.a},h.Ll=function(){return null},h.Ml=function(){return Cn(),Cn(),_o},h.xe=function(){return this.c==ET&&mt(this,J1t(this.d,this.b)),this.c},h.Nl=function(){return 0},h.a=-2,h.c=ET,I(us,"BasicExtendedMetaData/EClassExtendedMetaDataImpl",1181),D(1182,1,{},sct),h.Jl=function(){return this.a==(eE(),SY)&&Mt(this,VSn(this.f,this.b)),this.a},h.Kl=function(){return 0},h.Ll=function(){return this.c==(eE(),SY)&&Je(this,USn(this.f,this.b)),this.c},h.Ml=function(){return!this.d&&Wt(this,LAn(this.f,this.b)),this.d},h.xe=function(){return this.e==ET&&_n(this,J1t(this.f,this.b)),this.e},h.Nl=function(){return this.g==-2&&Yt(this,lxn(this.f,this.b)),this.g},h.e=ET,h.g=-2,I(us,"BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl",1182),D(1180,1,{},Ftt),h.b=!1,h.c=!1,I(us,"BasicExtendedMetaData/EPackageExtendedMetaDataImpl",1180),D(1183,1,{},act),h.c=-2,h.e=ET,h.f=ET,I(us,"BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl",1183),D(593,632,kc,Jq),h.Lj=function(){return this.c},h.ol=function(){return!1},h.Wi=function(t,n){return n},h.c=0,I(us,"EDataTypeEList",593);var HPe=ks(us,"FeatureMap");D(78,593,{3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},Ls),h.bd=function(t,n){uCn(this,t,l(n,76))},h.Fc=function(t){return _Tn(this,l(t,76))},h.Hi=function(t){Ogn(this,l(t,76))},h.Nj=function(t,n){return e0n(this,l(t,76),n)},h.Oj=function(t,n){return d4e(this,l(t,76),n)},h.Ti=function(t,n){return P_n(this,t,n)},h.Wi=function(t,n){return xMn(this,t,l(n,76))},h.hd=function(t,n){return XCn(this,t,l(n,76))},h.Uj=function(t,n){return t0n(this,l(t,76),n)},h.Vj=function(t,n){return uit(this,l(t,76),n)},h.Wj=function(t,n,r){return Q8n(this,l(t,76),l(n,76),r)},h.Zi=function(t,n){return Aue(this,t,l(n,76))},h.Ol=function(t,n){return fke(this,t,n)},h.cd=function(t,n){var r,a,o,f,g,w,E,C,L;for(C=new Lw(n.gc()),o=n.Kc();o.Ob();)if(a=l(o.Pb(),76),f=a.Lk(),up(this.e,f))(!f.Si()||!qH(this,f,a.md())&&!jE(C,a))&&qr(C,a);else{for(L=Wu(this.e.Dh(),f),r=l(this.g,124),g=!0,w=0;w=0;)if(n=t[this.c],this.k.am(n.Lk()))return this.j=this.f?n:n.md(),this.i=-2,!0;return this.i=-1,this.g=-1,!1},I(us,"BasicFeatureMap/FeatureEIterator",420),D(676,420,lg,Use),h.ul=function(){return!0},I(us,"BasicFeatureMap/ResolvingFeatureEIterator",676),D(968,496,KG,Snt),h.pj=function(){return this},I(us,"EContentsEList/1",968),D(969,496,KG,Xtt),h.ul=function(){return!1},I(us,"EContentsEList/2",969),D(967,287,WG,_nt),h.wl=function(t){},h.Ob=function(){return!1},h.Sb=function(){return!1},I(us,"EContentsEList/FeatureIteratorImpl/1",967),D(840,593,kc,yye),h.Ni=function(){this.a=!0},h.Qj=function(){return this.a},h.Gk=function(){var t;$r(this),hh(this.e)?(t=this.a,this.a=!1,Ni(this.e,new h0(this.e,2,this.c,t,!1))):this.a=!1},h.a=!1,I(us,"EDataTypeEList/Unsettable",840),D(1958,593,kc,Nnt),h.Si=function(){return!0},I(us,"EDataTypeUniqueEList",1958),D(1959,840,kc,Pnt),h.Si=function(){return!0},I(us,"EDataTypeUniqueEList/Unsettable",1959),D(147,83,kc,ml),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectContainmentEList/Resolving",147),D(1184,555,kc,Bnt),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectContainmentEList/Unsettable/Resolving",1184),D(766,14,kc,a4e),h.Ni=function(){this.a=!0},h.Qj=function(){return this.a},h.Gk=function(){var t;$r(this),hh(this.e)?(t=this.a,this.a=!1,Ni(this.e,new h0(this.e,2,this.c,t,!1))):this.a=!1},h.a=!1,I(us,"EObjectContainmentWithInverseEList/Unsettable",766),D(1222,766,kc,Yrt),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectContainmentWithInverseEList/Unsettable/Resolving",1222),D(757,505,kc,xye),h.Ni=function(){this.a=!0},h.Qj=function(){return this.a},h.Gk=function(){var t;$r(this),hh(this.e)?(t=this.a,this.a=!1,Ni(this.e,new h0(this.e,2,this.c,t,!1))):this.a=!1},h.a=!1,I(us,"EObjectEList/Unsettable",757),D(338,505,kc,$5),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectResolvingEList",338),D(1844,757,kc,Fnt),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectResolvingEList/Unsettable",1844),D(1527,1,{},bre);var Z_t;I(us,"EObjectValidator",1527),D(559,505,kc,pH),h.il=function(){return this.d},h.jl=function(){return this.b},h.Mj=function(){return!0},h.ml=function(){return!0},h.b=0,I(us,"EObjectWithInverseEList",559),D(1225,559,kc,Xrt),h.ll=function(){return!0},I(us,"EObjectWithInverseEList/ManyInverse",1225),D(635,559,kc,fae),h.Ni=function(){this.a=!0},h.Qj=function(){return this.a},h.Gk=function(){var t;$r(this),hh(this.e)?(t=this.a,this.a=!1,Ni(this.e,new h0(this.e,2,this.c,t,!1))):this.a=!1},h.a=!1,I(us,"EObjectWithInverseEList/Unsettable",635),D(1224,635,kc,Qrt),h.ll=function(){return!0},I(us,"EObjectWithInverseEList/Unsettable/ManyInverse",1224),D(767,559,kc,o4e),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectWithInverseResolvingEList",767),D(32,767,kc,Ln),h.ll=function(){return!0},I(us,"EObjectWithInverseResolvingEList/ManyInverse",32),D(768,635,kc,c4e),h.nl=function(){return!0},h.Wi=function(t,n){return Ex(this,t,l(n,58))},I(us,"EObjectWithInverseResolvingEList/Unsettable",768),D(1223,768,kc,Jrt),h.ll=function(){return!0},I(us,"EObjectWithInverseResolvingEList/Unsettable/ManyInverse",1223),D(1185,632,kc),h.Li=function(){return(this.b&1792)==0},h.Ni=function(){this.b|=1},h.kl=function(){return(this.b&4)!=0},h.Mj=function(){return(this.b&40)!=0},h.ll=function(){return(this.b&16)!=0},h.ml=function(){return(this.b&8)!=0},h.nl=function(){return(this.b&r4)!=0},h.al=function(){return(this.b&32)!=0},h.ol=function(){return(this.b&m0)!=0},h.fk=function(t){return this.d?Rct(this.d,t):this.Lk().Hk().fk(t)},h.Qj=function(){return this.b&2?(this.b&1)!=0:this.i!=0},h.Si=function(){return(this.b&128)!=0},h.Gk=function(){var t;$r(this),this.b&2&&(hh(this.e)?(t=(this.b&1)!=0,this.b&=-2,xk(this,new h0(this.e,2,ms(this.e.Dh(),this.Lk()),t,!1))):this.b&=-2)},h.Yi=function(){return(this.b&1536)==0},h.b=0,I(us,"EcoreEList/Generic",1185),D(1186,1185,kc,Vat),h.Lk=function(){return this.a},I(us,"EcoreEList/Dynamic",1186),D(765,66,Bd,kwe),h.aj=function(t){return bN(this.a.a,t)},I(us,"EcoreEMap/1",765),D(764,83,kc,a5e),h.Mi=function(t,n){oU(this.b,l(n,136))},h.Oi=function(t,n){zft(this.b)},h.Pi=function(t,n,r){var a;++(a=this.b,l(n,136),a).e},h.Qi=function(t,n){Fce(this.b,l(n,136))},h.Ri=function(t,n,r){Fce(this.b,l(r,136)),qe(r)===qe(n)&&l(r,136).Ci(Jln(l(n,136).ld())),oU(this.b,l(n,136))},I(us,"EcoreEMap/DelegateEObjectContainmentEList",764),D(1220,141,ASe,ift),I(us,"EcoreEMap/Unsettable",1220),D(1221,764,kc,Zrt),h.Ni=function(){this.a=!0},h.Qj=function(){return this.a},h.Gk=function(){var t;$r(this),hh(this.e)?(t=this.a,this.a=!1,Ni(this.e,new h0(this.e,2,this.c,t,!1))):this.a=!1},h.a=!1,I(us,"EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList",1221),D(1189,215,m6,Ust),h.a=!1,h.b=!1,I(us,"EcoreUtil/Copier",1189),D(759,1,Oa,Lct),h.Nb=function(t){Za(this,t)},h.Ob=function(){return F1t(this)},h.Pb=function(){var t;return F1t(this),t=this.b,this.b=null,t},h.Qb=function(){this.a.Qb()},I(us,"EcoreUtil/ProperContentIterator",759),D(1528,1527,{},dz);var eAt;I(us,"EcoreValidator",1528);var tAt;ks(us,"FeatureMapUtil/Validator"),D(1295,1,{2041:1},v5),h.am=function(t){return!0},I(us,"FeatureMapUtil/1",1295),D(773,1,{2041:1},qke),h.am=function(t){var n;return this.c==t?!0:(n=Bt(cr(this.a,t)),n==null?QSn(this,t)?(Lut(this.a,t,(Hn(),ST)),!0):(Lut(this.a,t,(Hn(),Pb)),!1):n==(Hn(),ST))},h.e=!1;var spe;I(us,"FeatureMapUtil/BasicValidator",773),D(774,45,m6,vye),I(us,"FeatureMapUtil/BasicValidator/Cache",774),D(509,56,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,71:1,97:1},yO),h.bd=function(t,n){vbt(this.c,this.b,t,n)},h.Fc=function(t){return fke(this.c,this.b,t)},h.cd=function(t,n){return vLn(this.c,this.b,t,n)},h.Gc=function(t){return F_(this,t)},h.Gi=function(t,n){dwn(this.c,this.b,t,n)},h.Wk=function(t,n){return ike(this.c,this.b,t,n)},h.$i=function(t){return qU(this.c,this.b,t,!1)},h.Ii=function(){return cnt(this.c,this.b)},h.Ji=function(){return jln(this.c,this.b)},h.Ki=function(t){return vvn(this.c,this.b,t)},h.Xk=function(t,n){return Irt(this,t,n)},h.$b=function(){_8(this)},h.Hc=function(t){return qH(this.c,this.b,t)},h.Ic=function(t){return m3n(this.c,this.b,t)},h.Xb=function(t){return qU(this.c,this.b,t,!0)},h.Fk=function(t){return this},h.dd=function(t){return Cmn(this.c,this.b,t)},h.dc=function(){return _q(this)},h.Qj=function(){return!FN(this.c,this.b)},h.Kc=function(){return rwn(this.c,this.b)},h.ed=function(){return iwn(this.c,this.b)},h.fd=function(t){return P4n(this.c,this.b,t)},h.Ti=function(t,n){return Omt(this.c,this.b,t,n)},h.Ui=function(t,n){xvn(this.c,this.b,t,n)},h.gd=function(t){return hpt(this.c,this.b,t)},h.Mc=function(t){return y_n(this.c,this.b,t)},h.hd=function(t,n){return qmt(this.c,this.b,t,n)},h.Wb=function(t){EU(this.c,this.b),F_(this,l(t,15))},h.gc=function(){return N4n(this.c,this.b)},h.Pc=function(){return _bn(this.c,this.b)},h.Qc=function(t){return Smn(this.c,this.b,t)},h.Ib=function(){var t,n;for(n=new Up,n.a+="[",t=cnt(this.c,this.b);_ce(t);)Xo(n,j_(iU(t))),_ce(t)&&(n.a+=Co);return n.a+="]",n.a},h.Gk=function(){EU(this.c,this.b)},I(us,"FeatureMapUtil/FeatureEList",509),D(644,39,YP,Eoe),h.hj=function(t){return SA(this,t)},h.mj=function(t){var n,r,a,o,f,g,w;switch(this.d){case 1:case 2:{if(f=t.jj(),qe(f)===qe(this.c)&&SA(this,null)==t.hj(null))return this.g=t.ij(),t.gj()==1&&(this.d=1),!0;break}case 3:{switch(o=t.gj(),o){case 3:{if(f=t.jj(),qe(f)===qe(this.c)&&SA(this,null)==t.hj(null))return this.d=5,n=new Lw(2),qr(n,this.g),qr(n,t.ij()),this.g=n,!0;break}}break}case 5:{switch(o=t.gj(),o){case 3:{if(f=t.jj(),qe(f)===qe(this.c)&&SA(this,null)==t.hj(null))return r=l(this.g,16),r.Fc(t.ij()),!0;break}}break}case 4:{switch(o=t.gj(),o){case 3:{if(f=t.jj(),qe(f)===qe(this.c)&&SA(this,null)==t.hj(null))return this.d=1,this.g=t.ij(),!0;break}case 4:{if(f=t.jj(),qe(f)===qe(this.c)&&SA(this,null)==t.hj(null))return this.d=6,w=new Lw(2),qr(w,this.n),qr(w,t.kj()),this.n=w,g=he(le(Vr,1),di,28,15,[this.o,t.lj()]),this.g=g,!0;break}}break}case 6:{switch(o=t.gj(),o){case 4:{if(f=t.jj(),qe(f)===qe(this.c)&&SA(this,null)==t.hj(null))return r=l(this.n,16),r.Fc(t.kj()),g=l(this.g,53),a=We(Vr,di,28,g.length+1,15,1),pu(g,0,a,0,g.length),a[g.length]=t.lj(),this.g=a,!0;break}}break}}return!1},I(us,"FeatureMapUtil/FeatureENotificationImpl",644),D(564,509,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},nH),h.Ol=function(t,n){return fke(this.c,t,n)},h.Pl=function(t,n,r){return ike(this.c,t,n,r)},h.Ql=function(t,n,r){return Mke(this.c,t,n,r)},h.Rl=function(){return this},h.Sl=function(t,n){return pP(this.c,t,n)},h.Tl=function(t){return l(qU(this.c,this.b,t,!1),76).Lk()},h.Ul=function(t){return l(qU(this.c,this.b,t,!1),76).md()},h.Vl=function(){return this.a},h.Wl=function(t){return!FN(this.c,t)},h.Xl=function(t,n){HU(this.c,t,n)},h.Yl=function(t){return oft(this.c,t)},h.Zl=function(t){jdt(this.c,t)},I(us,"FeatureMapUtil/FeatureFeatureMap",564),D(1294,1,i0e,Ptt),h.Fk=function(t){return qU(this.b,this.a,-1,t)},h.Qj=function(){return!FN(this.b,this.a)},h.Wb=function(t){HU(this.b,this.a,t)},h.Gk=function(){EU(this.b,this.a)},I(us,"FeatureMapUtil/FeatureValue",1294);var c9,ape,ope,u9,nAt,gF=ks(nK,"AnyType");D(680,63,lp,Jie),I(nK,"InvalidDatatypeValueException",680);var AY=ks(nK,M5t),pF=ks(nK,D5t),VPe=ks(nK,I5t),rAt,tu,UPe,Sv,iAt,sAt,aAt,oAt,cAt,uAt,lAt,hAt,fAt,dAt,gAt,c7,pAt,u7,HM,bAt,C3,bF,mF,mAt,VM,UM;D(844,516,{110:1,94:1,93:1,58:1,54:1,99:1,857:1},zwe),h.Lh=function(t,n,r){switch(t){case 0:return r?(!this.c&&(this.c=new Ls(this,0)),this.c):(!this.c&&(this.c=new Ls(this,0)),this.c.b);case 1:return r?(!this.c&&(this.c=new Ls(this,0)),l(ku(this.c,(Gi(),Sv)),160)):(!this.c&&(this.c=new Ls(this,0)),l(l(ku(this.c,(Gi(),Sv)),160),220)).Vl();case 2:return r?(!this.b&&(this.b=new Ls(this,2)),this.b):(!this.b&&(this.b=new Ls(this,2)),this.b.b)}return sf(this,t-yr(this.ii()),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():this.ii(),t),n,r)},h.Uh=function(t,n,r){var a;switch(n){case 0:return!this.c&&(this.c=new Ls(this,0)),hP(this.c,t,r);case 1:return(!this.c&&(this.c=new Ls(this,0)),l(l(ku(this.c,(Gi(),Sv)),160),71)).Xk(t,r);case 2:return!this.b&&(this.b=new Ls(this,2)),hP(this.b,t,r)}return a=l(Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():this.ii(),n),69),a.wk().Ak(this,V6e(this),n-yr(this.ii()),t,r)},h.Wh=function(t){switch(t){case 0:return!!this.c&&this.c.i!=0;case 1:return!(!this.c&&(this.c=new Ls(this,0)),l(ku(this.c,(Gi(),Sv)),160)).dc();case 2:return!!this.b&&this.b.i!=0}return nf(this,t-yr(this.ii()),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():this.ii(),t))},h.bi=function(t,n){switch(t){case 0:!this.c&&(this.c=new Ls(this,0)),$O(this.c,n);return;case 1:(!this.c&&(this.c=new Ls(this,0)),l(l(ku(this.c,(Gi(),Sv)),160),220)).Wb(n);return;case 2:!this.b&&(this.b=new Ls(this,2)),$O(this.b,n);return}uf(this,t-yr(this.ii()),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():this.ii(),t),n)},h.ii=function(){return Gi(),UPe},h.ki=function(t){switch(t){case 0:!this.c&&(this.c=new Ls(this,0)),$r(this.c);return;case 1:(!this.c&&(this.c=new Ls(this,0)),l(ku(this.c,(Gi(),Sv)),160)).$b();return;case 2:!this.b&&(this.b=new Ls(this,2)),$r(this.b);return}cf(this,t-yr(this.ii()),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():this.ii(),t))},h.Ib=function(){var t;return this.j&4?g0(this):(t=new Af(g0(this)),t.a+=" (mixed: ",O_(t,this.c),t.a+=", anyAttribute: ",O_(t,this.b),t.a+=")",t.a)},I(ea,"AnyTypeImpl",844),D(681,516,{110:1,94:1,93:1,58:1,54:1,99:1,2119:1,681:1},yre),h.Lh=function(t,n,r){switch(t){case 0:return this.a;case 1:return this.b}return sf(this,t-yr((Gi(),c7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():c7,t),n,r)},h.Wh=function(t){switch(t){case 0:return this.a!=null;case 1:return this.b!=null}return nf(this,t-yr((Gi(),c7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():c7,t))},h.bi=function(t,n){switch(t){case 0:vr(this,ei(n));return;case 1:pr(this,ei(n));return}uf(this,t-yr((Gi(),c7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():c7,t),n)},h.ii=function(){return Gi(),c7},h.ki=function(t){switch(t){case 0:this.a=null;return;case 1:this.b=null;return}cf(this,t-yr((Gi(),c7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():c7,t))},h.Ib=function(){var t;return this.j&4?g0(this):(t=new Af(g0(this)),t.a+=" (data: ",Xo(t,this.a),t.a+=", target: ",Xo(t,this.b),t.a+=")",t.a)},h.a=null,h.b=null,I(ea,"ProcessingInstructionImpl",681),D(682,844,{110:1,94:1,93:1,58:1,54:1,99:1,857:1,2120:1,682:1},fJe),h.Lh=function(t,n,r){switch(t){case 0:return r?(!this.c&&(this.c=new Ls(this,0)),this.c):(!this.c&&(this.c=new Ls(this,0)),this.c.b);case 1:return r?(!this.c&&(this.c=new Ls(this,0)),l(ku(this.c,(Gi(),Sv)),160)):(!this.c&&(this.c=new Ls(this,0)),l(l(ku(this.c,(Gi(),Sv)),160),220)).Vl();case 2:return r?(!this.b&&(this.b=new Ls(this,2)),this.b):(!this.b&&(this.b=new Ls(this,2)),this.b.b);case 3:return!this.c&&(this.c=new Ls(this,0)),ei(pP(this.c,(Gi(),HM),!0));case 4:return l4e(this.a,(!this.c&&(this.c=new Ls(this,0)),ei(pP(this.c,(Gi(),HM),!0))));case 5:return this.a}return sf(this,t-yr((Gi(),u7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():u7,t),n,r)},h.Wh=function(t){switch(t){case 0:return!!this.c&&this.c.i!=0;case 1:return!(!this.c&&(this.c=new Ls(this,0)),l(ku(this.c,(Gi(),Sv)),160)).dc();case 2:return!!this.b&&this.b.i!=0;case 3:return!this.c&&(this.c=new Ls(this,0)),ei(pP(this.c,(Gi(),HM),!0))!=null;case 4:return l4e(this.a,(!this.c&&(this.c=new Ls(this,0)),ei(pP(this.c,(Gi(),HM),!0))))!=null;case 5:return!!this.a}return nf(this,t-yr((Gi(),u7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():u7,t))},h.bi=function(t,n){switch(t){case 0:!this.c&&(this.c=new Ls(this,0)),$O(this.c,n);return;case 1:(!this.c&&(this.c=new Ls(this,0)),l(l(ku(this.c,(Gi(),Sv)),160),220)).Wb(n);return;case 2:!this.b&&(this.b=new Ls(this,2)),$O(this.b,n);return;case 3:J5e(this,ei(n));return;case 4:J5e(this,u4e(this.a,n));return;case 5:Nn(this,l(n,156));return}uf(this,t-yr((Gi(),u7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():u7,t),n)},h.ii=function(){return Gi(),u7},h.ki=function(t){switch(t){case 0:!this.c&&(this.c=new Ls(this,0)),$r(this.c);return;case 1:(!this.c&&(this.c=new Ls(this,0)),l(ku(this.c,(Gi(),Sv)),160)).$b();return;case 2:!this.b&&(this.b=new Ls(this,2)),$r(this.b);return;case 3:!this.c&&(this.c=new Ls(this,0)),HU(this.c,(Gi(),HM),null);return;case 4:J5e(this,u4e(this.a,null));return;case 5:this.a=null;return}cf(this,t-yr((Gi(),u7)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():u7,t))},I(ea,"SimpleAnyTypeImpl",682),D(683,516,{110:1,94:1,93:1,58:1,54:1,99:1,2121:1,683:1},dJe),h.Lh=function(t,n,r){switch(t){case 0:return r?(!this.a&&(this.a=new Ls(this,0)),this.a):(!this.a&&(this.a=new Ls(this,0)),this.a.b);case 1:return r?(!this.b&&(this.b=new xl((Tn(),No),Yc,this,1)),this.b):(!this.b&&(this.b=new xl((Tn(),No),Yc,this,1)),iN(this.b));case 2:return r?(!this.c&&(this.c=new xl((Tn(),No),Yc,this,2)),this.c):(!this.c&&(this.c=new xl((Tn(),No),Yc,this,2)),iN(this.c));case 3:return!this.a&&(this.a=new Ls(this,0)),ku(this.a,(Gi(),bF));case 4:return!this.a&&(this.a=new Ls(this,0)),ku(this.a,(Gi(),mF));case 5:return!this.a&&(this.a=new Ls(this,0)),ku(this.a,(Gi(),VM));case 6:return!this.a&&(this.a=new Ls(this,0)),ku(this.a,(Gi(),UM))}return sf(this,t-yr((Gi(),C3)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():C3,t),n,r)},h.Uh=function(t,n,r){var a;switch(n){case 0:return!this.a&&(this.a=new Ls(this,0)),hP(this.a,t,r);case 1:return!this.b&&(this.b=new xl((Tn(),No),Yc,this,1)),Uq(this.b,t,r);case 2:return!this.c&&(this.c=new xl((Tn(),No),Yc,this,2)),Uq(this.c,t,r);case 5:return!this.a&&(this.a=new Ls(this,0)),Irt(ku(this.a,(Gi(),VM)),t,r)}return a=l(Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():(Gi(),C3),n),69),a.wk().Ak(this,V6e(this),n-yr((Gi(),C3)),t,r)},h.Wh=function(t){switch(t){case 0:return!!this.a&&this.a.i!=0;case 1:return!!this.b&&this.b.f!=0;case 2:return!!this.c&&this.c.f!=0;case 3:return!this.a&&(this.a=new Ls(this,0)),!_q(ku(this.a,(Gi(),bF)));case 4:return!this.a&&(this.a=new Ls(this,0)),!_q(ku(this.a,(Gi(),mF)));case 5:return!this.a&&(this.a=new Ls(this,0)),!_q(ku(this.a,(Gi(),VM)));case 6:return!this.a&&(this.a=new Ls(this,0)),!_q(ku(this.a,(Gi(),UM)))}return nf(this,t-yr((Gi(),C3)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():C3,t))},h.bi=function(t,n){switch(t){case 0:!this.a&&(this.a=new Ls(this,0)),$O(this.a,n);return;case 1:!this.b&&(this.b=new xl((Tn(),No),Yc,this,1)),_V(this.b,n);return;case 2:!this.c&&(this.c=new xl((Tn(),No),Yc,this,2)),_V(this.c,n);return;case 3:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),bF))),!this.a&&(this.a=new Ls(this,0)),F_(ku(this.a,bF),l(n,16));return;case 4:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),mF))),!this.a&&(this.a=new Ls(this,0)),F_(ku(this.a,mF),l(n,16));return;case 5:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),VM))),!this.a&&(this.a=new Ls(this,0)),F_(ku(this.a,VM),l(n,16));return;case 6:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),UM))),!this.a&&(this.a=new Ls(this,0)),F_(ku(this.a,UM),l(n,16));return}uf(this,t-yr((Gi(),C3)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():C3,t),n)},h.ii=function(){return Gi(),C3},h.ki=function(t){switch(t){case 0:!this.a&&(this.a=new Ls(this,0)),$r(this.a);return;case 1:!this.b&&(this.b=new xl((Tn(),No),Yc,this,1)),this.b.c.$b();return;case 2:!this.c&&(this.c=new xl((Tn(),No),Yc,this,2)),this.c.c.$b();return;case 3:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),bF)));return;case 4:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),mF)));return;case 5:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),VM)));return;case 6:!this.a&&(this.a=new Ls(this,0)),_8(ku(this.a,(Gi(),UM)));return}cf(this,t-yr((Gi(),C3)),Mn(this.j&2?(!this.k&&(this.k=new Sf),this.k).Nk():C3,t))},h.Ib=function(){var t;return this.j&4?g0(this):(t=new Af(g0(this)),t.a+=" (mixed: ",O_(t,this.a),t.a+=")",t.a)},I(ea,"XMLTypeDocumentRootImpl",683),D(2028,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1,2122:1},uk),h.ri=function(t,n){switch(t.hk()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return n==null?null:xc(n);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return ei(n);case 6:return hfn(l(n,195));case 12:case 47:case 49:case 11:return Lvt(this,t,n);case 13:return n==null?null:kLn(l(n,247));case 15:case 14:return n==null?null:_gn(ze(Ge(n)));case 17:return Sgt((Gi(),n));case 18:return Sgt(n);case 21:case 20:return n==null?null:Agn(l(n,161).a);case 27:return ffn(l(n,195));case 30:return $dt((Gi(),l(n,15)));case 31:return $dt(l(n,15));case 40:return gfn((Gi(),n));case 42:return _gt((Gi(),n));case 43:return _gt(n);case 59:case 48:return dfn((Gi(),n));default:throw ue(new Yn(yT+t.xe()+t3))}},h.si=function(t){var n,r,a,o,f;switch(t.G==-1&&(t.G=(r=Ah(t),r?f2(r.vi(),t):-1)),t.G){case 0:return n=new zwe,n;case 1:return a=new yre,a;case 2:return o=new fJe,o;case 3:return f=new dJe,f;default:throw ue(new Yn(qfe+t.zb+t3))}},h.ti=function(t,n){var r,a,o,f,g,w,E,C,L,B,z,V,J,te,fe,Te;switch(t.hk()){case 5:case 52:case 4:return n;case 6:return y6n(n);case 8:case 7:return n==null?null:axn(n);case 9:return n==null?null:fN(Oh((a=Tu(n,!0),a.length>0&&(Xn(0,a.length),a.charCodeAt(0)==43)?(Xn(1,a.length+1),a.substr(1)):a),-128,127)<<24>>24);case 10:return n==null?null:fN(Oh((o=Tu(n,!0),o.length>0&&(Xn(0,o.length),o.charCodeAt(0)==43)?(Xn(1,o.length+1),o.substr(1)):o),-128,127)<<24>>24);case 11:return ei(Kw(this,(Gi(),aAt),n));case 12:return ei(Kw(this,(Gi(),oAt),n));case 13:return n==null?null:new h3e(Tu(n,!0));case 15:case 14:return LTn(n);case 16:return ei(Kw(this,(Gi(),cAt),n));case 17:return q1t((Gi(),n));case 18:return q1t(n);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return Tu(n,!0);case 21:case 20:return jTn(n);case 22:return ei(Kw(this,(Gi(),uAt),n));case 23:return ei(Kw(this,(Gi(),lAt),n));case 24:return ei(Kw(this,(Gi(),hAt),n));case 25:return ei(Kw(this,(Gi(),fAt),n));case 26:return ei(Kw(this,(Gi(),dAt),n));case 27:return c6n(n);case 30:return H1t((Gi(),n));case 31:return H1t(n);case 32:return n==null?null:pt(Oh((L=Tu(n,!0),L.length>0&&(Xn(0,L.length),L.charCodeAt(0)==43)?(Xn(1,L.length+1),L.substr(1)):L),lo,Ii));case 33:return n==null?null:new ob((B=Tu(n,!0),B.length>0&&(Xn(0,B.length),B.charCodeAt(0)==43)?(Xn(1,B.length+1),B.substr(1)):B));case 34:return n==null?null:pt(Oh((z=Tu(n,!0),z.length>0&&(Xn(0,z.length),z.charCodeAt(0)==43)?(Xn(1,z.length+1),z.substr(1)):z),lo,Ii));case 36:return n==null?null:ap(KU((V=Tu(n,!0),V.length>0&&(Xn(0,V.length),V.charCodeAt(0)==43)?(Xn(1,V.length+1),V.substr(1)):V)));case 37:return n==null?null:ap(KU((J=Tu(n,!0),J.length>0&&(Xn(0,J.length),J.charCodeAt(0)==43)?(Xn(1,J.length+1),J.substr(1)):J)));case 40:return s7n((Gi(),n));case 42:return V1t((Gi(),n));case 43:return V1t(n);case 44:return n==null?null:new ob((te=Tu(n,!0),te.length>0&&(Xn(0,te.length),te.charCodeAt(0)==43)?(Xn(1,te.length+1),te.substr(1)):te));case 45:return n==null?null:new ob((fe=Tu(n,!0),fe.length>0&&(Xn(0,fe.length),fe.charCodeAt(0)==43)?(Xn(1,fe.length+1),fe.substr(1)):fe));case 46:return Tu(n,!1);case 47:return ei(Kw(this,(Gi(),gAt),n));case 59:case 48:return i7n((Gi(),n));case 49:return ei(Kw(this,(Gi(),pAt),n));case 50:return n==null?null:_E(Oh((Te=Tu(n,!0),Te.length>0&&(Xn(0,Te.length),Te.charCodeAt(0)==43)?(Xn(1,Te.length+1),Te.substr(1)):Te),JG,32767)<<16>>16);case 51:return n==null?null:_E(Oh((f=Tu(n,!0),f.length>0&&(Xn(0,f.length),f.charCodeAt(0)==43)?(Xn(1,f.length+1),f.substr(1)):f),JG,32767)<<16>>16);case 53:return ei(Kw(this,(Gi(),bAt),n));case 55:return n==null?null:_E(Oh((g=Tu(n,!0),g.length>0&&(Xn(0,g.length),g.charCodeAt(0)==43)?(Xn(1,g.length+1),g.substr(1)):g),JG,32767)<<16>>16);case 56:return n==null?null:_E(Oh((w=Tu(n,!0),w.length>0&&(Xn(0,w.length),w.charCodeAt(0)==43)?(Xn(1,w.length+1),w.substr(1)):w),JG,32767)<<16>>16);case 57:return n==null?null:ap(KU((E=Tu(n,!0),E.length>0&&(Xn(0,E.length),E.charCodeAt(0)==43)?(Xn(1,E.length+1),E.substr(1)):E)));case 58:return n==null?null:ap(KU((C=Tu(n,!0),C.length>0&&(Xn(0,C.length),C.charCodeAt(0)==43)?(Xn(1,C.length+1),C.substr(1)):C)));case 60:return n==null?null:pt(Oh((r=Tu(n,!0),r.length>0&&(Xn(0,r.length),r.charCodeAt(0)==43)?(Xn(1,r.length+1),r.substr(1)):r),lo,Ii));case 61:return n==null?null:pt(Oh(Tu(n,!0),lo,Ii));default:throw ue(new Yn(yT+t.xe()+t3))}};var vAt,GPe,wAt,KPe;I(ea,"XMLTypeFactoryImpl",2028),D(594,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1,2044:1,594:1},dat),h.N=!1,h.O=!1;var yAt=!1;I(ea,"XMLTypePackageImpl",594),D(1961,1,{851:1},lk),h.Kk=function(){return xke(),LAt},I(ea,"XMLTypePackageImpl/1",1961),D(1970,1,yi,qS),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/10",1970),D(1971,1,yi,mre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/11",1971),D(1972,1,yi,vre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/12",1972),D(1973,1,yi,p8),h.fk=function(t){return fy(t)},h.gk=function(t){return We(ta,dt,345,t,7,1)},I(ea,"XMLTypePackageImpl/13",1973),D(1974,1,yi,R$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/14",1974),D(1975,1,yi,j$),h.fk=function(t){return De(t,15)},h.gk=function(t){return We(mf,Qy,15,t,0,1)},I(ea,"XMLTypePackageImpl/15",1975),D(1976,1,yi,wre),h.fk=function(t){return De(t,15)},h.gk=function(t){return We(mf,Qy,15,t,0,1)},I(ea,"XMLTypePackageImpl/16",1976),D(1977,1,yi,$$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/17",1977),D(1978,1,yi,z$),h.fk=function(t){return De(t,161)},h.gk=function(t){return We(_T,dt,161,t,0,1)},I(ea,"XMLTypePackageImpl/18",1978),D(1979,1,yi,NI),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/19",1979),D(1962,1,yi,xre),h.fk=function(t){return De(t,857)},h.gk=function(t){return We(gF,Rn,857,t,0,1)},I(ea,"XMLTypePackageImpl/2",1962),D(1980,1,yi,HS),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/20",1980),D(1981,1,yi,kre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/21",1981),D(1982,1,yi,Ere),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/22",1982),D(1983,1,yi,Tre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/23",1983),D(1984,1,yi,Cre),h.fk=function(t){return De(t,195)},h.gk=function(t){return We(Al,dt,195,t,0,2)},I(ea,"XMLTypePackageImpl/24",1984),D(1985,1,yi,Sre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/25",1985),D(1986,1,yi,q$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/26",1986),D(1987,1,yi,_re),h.fk=function(t){return De(t,15)},h.gk=function(t){return We(mf,Qy,15,t,0,1)},I(ea,"XMLTypePackageImpl/27",1987),D(1988,1,yi,Are),h.fk=function(t){return De(t,15)},h.gk=function(t){return We(mf,Qy,15,t,0,1)},I(ea,"XMLTypePackageImpl/28",1988),D(1989,1,yi,Lre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/29",1989),D(1963,1,yi,H$),h.fk=function(t){return De(t,681)},h.gk=function(t){return We(AY,Rn,2119,t,0,1)},I(ea,"XMLTypePackageImpl/3",1963),D(1990,1,yi,Mre),h.fk=function(t){return De(t,17)},h.gk=function(t){return We(ro,dt,17,t,0,1)},I(ea,"XMLTypePackageImpl/30",1990),D(1991,1,yi,Dre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/31",1991),D(1992,1,yi,VS),h.fk=function(t){return De(t,168)},h.gk=function(t){return We(r3,dt,168,t,0,1)},I(ea,"XMLTypePackageImpl/32",1992),D(1993,1,yi,Ire),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/33",1993),D(1994,1,yi,Ore),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/34",1994),D(1995,1,yi,Nre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/35",1995),D(1996,1,yi,Pre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/36",1996),D(1997,1,yi,Bre),h.fk=function(t){return De(t,15)},h.gk=function(t){return We(mf,Qy,15,t,0,1)},I(ea,"XMLTypePackageImpl/37",1997),D(1998,1,yi,Fre),h.fk=function(t){return De(t,15)},h.gk=function(t){return We(mf,Qy,15,t,0,1)},I(ea,"XMLTypePackageImpl/38",1998),D(1999,1,yi,V$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/39",1999),D(1964,1,yi,Rre),h.fk=function(t){return De(t,682)},h.gk=function(t){return We(pF,Rn,2120,t,0,1)},I(ea,"XMLTypePackageImpl/4",1964),D(2e3,1,yi,U$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/40",2e3),D(2001,1,yi,jre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/41",2001),D(2002,1,yi,PI),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/42",2002),D(2003,1,yi,$re),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/43",2003),D(2004,1,yi,G$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/44",2004),D(2005,1,yi,zre),h.fk=function(t){return De(t,191)},h.gk=function(t){return We(i3,dt,191,t,0,1)},I(ea,"XMLTypePackageImpl/45",2005),D(2006,1,yi,K$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/46",2006),D(2007,1,yi,qre),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/47",2007),D(2008,1,yi,W$),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/48",2008),D(2009,1,yi,Y$),h.fk=function(t){return De(t,191)},h.gk=function(t){return We(i3,dt,191,t,0,1)},I(ea,"XMLTypePackageImpl/49",2009),D(1965,1,yi,X$),h.fk=function(t){return De(t,683)},h.gk=function(t){return We(VPe,Rn,2121,t,0,1)},I(ea,"XMLTypePackageImpl/5",1965),D(2010,1,yi,BI),h.fk=function(t){return De(t,168)},h.gk=function(t){return We(r3,dt,168,t,0,1)},I(ea,"XMLTypePackageImpl/50",2010),D(2011,1,yi,w5),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/51",2011),D(2012,1,yi,US),h.fk=function(t){return De(t,17)},h.gk=function(t){return We(ro,dt,17,t,0,1)},I(ea,"XMLTypePackageImpl/52",2012),D(1966,1,yi,S1),h.fk=function(t){return Ia(t)},h.gk=function(t){return We(zt,dt,2,t,6,1)},I(ea,"XMLTypePackageImpl/6",1966),D(1967,1,yi,Q$),h.fk=function(t){return De(t,195)},h.gk=function(t){return We(Al,dt,195,t,0,2)},I(ea,"XMLTypePackageImpl/7",1967),D(1968,1,yi,hk),h.fk=function(t){return hy(t)},h.gk=function(t){return We(Ns,dt,485,t,8,1)},I(ea,"XMLTypePackageImpl/8",1968),D(1969,1,yi,FI),h.fk=function(t){return De(t,222)},h.gk=function(t){return We(jx,dt,222,t,0,1)},I(ea,"XMLTypePackageImpl/9",1969);var nd,N2,GM,LY,ye;D(55,63,lp,ri),I(y2,"RegEx/ParseException",55),D(836,1,{},J$),h.bm=function(t){return tr*16)throw ue(new ri(ai((Jr(),H4t))));r=r*16+o}while(!0);if(this.a!=125)throw ue(new ri(ai((Jr(),V4t))));if(r>TT)throw ue(new ri(ai((Jr(),U4t))));t=r}else{if(o=0,this.c!=0||(o=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(r=o,Li(this),this.c!=0||(o=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));r=r*16+o,t=r}break;case 117:if(a=0,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=n*16+a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=n*16+a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));n=n*16+a,t=n;break;case 118:if(Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=n*16+a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=n*16+a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=n*16+a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=n*16+a,Li(this),this.c!=0||(a=Wm(this.a))<0)throw ue(new ri(ai((Jr(),w2))));if(n=n*16+a,n>TT)throw ue(new ri(ai((Jr(),"parser.descappe.4"))));t=n;break;case 65:case 90:case 122:throw ue(new ri(ai((Jr(),G4t))))}return t},h.dm=function(t){var n,r;switch(t){case 100:r=(this.e&32)==32?_b("Nd",!0):(Di(),MY);break;case 68:r=(this.e&32)==32?_b("Nd",!1):(Di(),ZPe);break;case 119:r=(this.e&32)==32?_b("IsWord",!0):(Di(),lC);break;case 87:r=(this.e&32)==32?_b("IsWord",!1):(Di(),tBe);break;case 115:r=(this.e&32)==32?_b("IsSpace",!0):(Di(),l9);break;case 83:r=(this.e&32)==32?_b("IsSpace",!1):(Di(),eBe);break;default:throw ue(new Ac((n=t,G5t+n.toString(16))))}return r},h.em=function(t){var n,r,a,o,f,g,w,E,C,L,B,z;for(this.b=1,Li(this),n=null,this.c==0&&this.a==94?(Li(this),t?L=(Di(),Di(),new _h(5)):(n=(Di(),Di(),new _h(4)),Eu(n,0,TT),L=new _h(4))):L=(Di(),Di(),new _h(4)),o=!0;(z=this.c)!=1&&!(z==0&&this.a==93&&!o);){if(o=!1,r=this.a,a=!1,z==10)switch(r){case 100:case 68:case 119:case 87:case 115:case 83:Ky(L,this.dm(r)),a=!0;break;case 105:case 73:case 99:case 67:r=this.um(L,r),r<0&&(a=!0);break;case 112:case 80:if(B=w9e(this,r),!B)throw ue(new ri(ai((Jr(),t0e))));Ky(L,B),a=!0;break;default:r=this.cm()}else if(z==20){if(g=Nk(this.i,58,this.d),g<0)throw ue(new ri(ai((Jr(),kSe))));if(w=!0,co(this.i,this.d)==94&&(++this.d,w=!1),f=tf(this.i,this.d,g),E=vlt(f,w,(this.e&512)==512),!E)throw ue(new ri(ai((Jr(),R4t))));if(Ky(L,E),a=!0,g+1>=this.j||co(this.i,g+1)!=93)throw ue(new ri(ai((Jr(),kSe))));this.d=g+2}if(Li(this),!a)if(this.c!=0||this.a!=45)Eu(L,r,r);else{if(Li(this),(z=this.c)==1)throw ue(new ri(ai((Jr(),UG))));z==0&&this.a==93?(Eu(L,r,r),Eu(L,45,45)):(C=this.a,z==10&&(C=this.cm()),Li(this),Eu(L,r,C))}(this.e&m0)==m0&&this.c==0&&this.a==44&&Li(this)}if(this.c==1)throw ue(new ri(ai((Jr(),UG))));return n&&(nL(n,L),L=n),c6(L),eL(L),this.b=0,Li(this),L},h.fm=function(){var t,n,r,a;for(r=this.em(!1);(a=this.c)!=7;)if(t=this.a,a==0&&(t==45||t==38)||a==4){if(Li(this),this.c!=9)throw ue(new ri(ai((Jr(),$4t))));if(n=this.em(!1),a==4)Ky(r,n);else if(t==45)nL(r,n);else if(t==38)Cvt(r,n);else throw ue(new Ac("ASSERT"))}else throw ue(new ri(ai((Jr(),z4t))));return Li(this),r},h.gm=function(){var t,n;return t=this.a-48,n=(Di(),Di(),new coe(12,null,t)),!this.g&&(this.g=new jz),Rz(this.g,new Ewe(t)),Li(this),n},h.hm=function(){return Li(this),Di(),EAt},h.im=function(){return Li(this),Di(),kAt},h.jm=function(){throw ue(new ri(ai((Jr(),bf))))},h.km=function(){throw ue(new ri(ai((Jr(),bf))))},h.lm=function(){return Li(this),Eyn()},h.mm=function(){return Li(this),Di(),CAt},h.nm=function(){return Li(this),Di(),_At},h.om=function(){var t;if(this.d>=this.j||((t=co(this.i,this.d++))&65504)!=64)throw ue(new ri(ai((Jr(),P4t))));return Li(this),Di(),Di(),new ng(0,t-64)},h.pm=function(){return Li(this),SAn()},h.qm=function(){return Li(this),Di(),AAt},h.rm=function(){var t;return t=(Di(),Di(),new ng(0,105)),Li(this),t},h.sm=function(){return Li(this),Di(),SAt},h.tm=function(){return Li(this),Di(),TAt},h.um=function(t,n){return this.cm()},h.vm=function(){return Li(this),Di(),QPe},h.wm=function(){var t,n,r,a,o;if(this.d+1>=this.j)throw ue(new ri(ai((Jr(),I4t))));if(a=-1,n=null,t=co(this.i,this.d),49<=t&&t<=57){if(a=t-48,!this.g&&(this.g=new jz),Rz(this.g,new Ewe(a)),++this.d,co(this.i,this.d)!=41)throw ue(new ri(ai((Jr(),ov))));++this.d}else switch(t==63&&--this.d,Li(this),n=Gke(this),n.e){case 20:case 21:case 22:case 23:break;case 8:if(this.c!=7)throw ue(new ri(ai((Jr(),ov))));break;default:throw ue(new ri(ai((Jr(),O4t))))}if(Li(this),o=jw(this),r=null,o.e==2){if(o.Pm()!=2)throw ue(new ri(ai((Jr(),N4t))));r=o.Lm(1),o=o.Lm(0)}if(this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),Di(),Di(),new Zlt(a,n,o,r)},h.xm=function(){return Li(this),Di(),JPe},h.ym=function(){var t;if(Li(this),t=bH(24,jw(this)),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),t},h.zm=function(){var t;if(Li(this),t=bH(20,jw(this)),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),t},h.Am=function(){var t;if(Li(this),t=bH(22,jw(this)),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),t},h.Bm=function(){var t,n,r,a,o;for(t=0,r=0,n=-1;this.d=this.j)throw ue(new ri(ai((Jr(),ySe))));if(n==45){for(++this.d;this.d=this.j)throw ue(new ri(ai((Jr(),ySe))))}if(n==58){if(++this.d,Li(this),a=Wst(jw(this),t,r),this.c!=7)throw ue(new ri(ai((Jr(),ov))));Li(this)}else if(n==41)++this.d,Li(this),a=Wst(jw(this),t,r);else throw ue(new ri(ai((Jr(),D4t))));return a},h.Cm=function(){var t;if(Li(this),t=bH(21,jw(this)),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),t},h.Dm=function(){var t;if(Li(this),t=bH(23,jw(this)),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),t},h.Em=function(){var t,n;if(Li(this),t=this.f++,n=Bae(jw(this),t),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),n},h.Fm=function(){var t;if(Li(this),t=Bae(jw(this),0),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),t},h.Gm=function(t){return Li(this),this.c==5?(Li(this),oH(t,(Di(),Di(),new Ty(9,t)))):oH(t,(Di(),Di(),new Ty(3,t)))},h.Hm=function(t){var n;return Li(this),n=(Di(),Di(),new B_(2)),this.c==5?(Li(this),Qm(n,WM),Qm(n,t)):(Qm(n,t),Qm(n,WM)),n},h.Im=function(t){return Li(this),this.c==5?(Li(this),Di(),Di(),new Ty(9,t)):(Di(),Di(),new Ty(3,t))},h.a=0,h.b=0,h.c=0,h.d=0,h.e=0,h.f=1,h.g=null,h.j=0,I(y2,"RegEx/RegexParser",836),D(1947,836,{},gJe),h.bm=function(t){return!1},h.cm=function(){return eke(this)},h.dm=function(t){return YE(t)},h.em=function(t){return ywt(this)},h.fm=function(){throw ue(new ri(ai((Jr(),bf))))},h.gm=function(){throw ue(new ri(ai((Jr(),bf))))},h.hm=function(){throw ue(new ri(ai((Jr(),bf))))},h.im=function(){throw ue(new ri(ai((Jr(),bf))))},h.jm=function(){return Li(this),YE(67)},h.km=function(){return Li(this),YE(73)},h.lm=function(){throw ue(new ri(ai((Jr(),bf))))},h.mm=function(){throw ue(new ri(ai((Jr(),bf))))},h.nm=function(){throw ue(new ri(ai((Jr(),bf))))},h.om=function(){return Li(this),YE(99)},h.pm=function(){throw ue(new ri(ai((Jr(),bf))))},h.qm=function(){throw ue(new ri(ai((Jr(),bf))))},h.rm=function(){return Li(this),YE(105)},h.sm=function(){throw ue(new ri(ai((Jr(),bf))))},h.tm=function(){throw ue(new ri(ai((Jr(),bf))))},h.um=function(t,n){return Ky(t,YE(n)),-1},h.vm=function(){return Li(this),Di(),Di(),new ng(0,94)},h.wm=function(){throw ue(new ri(ai((Jr(),bf))))},h.xm=function(){return Li(this),Di(),Di(),new ng(0,36)},h.ym=function(){throw ue(new ri(ai((Jr(),bf))))},h.zm=function(){throw ue(new ri(ai((Jr(),bf))))},h.Am=function(){throw ue(new ri(ai((Jr(),bf))))},h.Bm=function(){throw ue(new ri(ai((Jr(),bf))))},h.Cm=function(){throw ue(new ri(ai((Jr(),bf))))},h.Dm=function(){throw ue(new ri(ai((Jr(),bf))))},h.Em=function(){var t;if(Li(this),t=Bae(jw(this),0),this.c!=7)throw ue(new ri(ai((Jr(),ov))));return Li(this),t},h.Fm=function(){throw ue(new ri(ai((Jr(),bf))))},h.Gm=function(t){return Li(this),oH(t,(Di(),Di(),new Ty(3,t)))},h.Hm=function(t){var n;return Li(this),n=(Di(),Di(),new B_(2)),Qm(n,t),Qm(n,WM),n},h.Im=function(t){return Li(this),Di(),Di(),new Ty(3,t)};var l7=null,cC=null;I(y2,"RegEx/ParserForXMLSchema",1947),D(122,1,CT,Xv),h.Jm=function(t){throw ue(new Ac("Not supported."))},h.Km=function(){return-1},h.Lm=function(t){return null},h.Mm=function(){return null},h.Nm=function(t){},h.Om=function(t){},h.Pm=function(){return 0},h.Ib=function(){return this.Qm(0)},h.Qm=function(t){return this.e==11?".":""},h.e=0;var WPe,uC,KM,xAt,YPe,P4=null,MY,cpe=null,XPe,WM,upe=null,QPe,JPe,ZPe,eBe,tBe,kAt,l9,EAt,TAt,CAt,SAt,lC,_At,AAt,BOn=I(y2,"RegEx/Token",122);D(138,122,{3:1,138:1,122:1},_h),h.Qm=function(t){var n,r,a;if(this.e==4)if(this==XPe)r=".";else if(this==MY)r="\\d";else if(this==lC)r="\\w";else if(this==l9)r="\\s";else{for(a=new Up,a.a+="[",n=0;n0&&(a.a+=","),this.b[n]===this.b[n+1]?Xo(a,gP(this.b[n])):(Xo(a,gP(this.b[n])),a.a+="-",Xo(a,gP(this.b[n+1])));a.a+="]",r=a.a}else if(this==ZPe)r="\\D";else if(this==tBe)r="\\W";else if(this==eBe)r="\\S";else{for(a=new Up,a.a+="[^",n=0;n0&&(a.a+=","),this.b[n]===this.b[n+1]?Xo(a,gP(this.b[n])):(Xo(a,gP(this.b[n])),a.a+="-",Xo(a,gP(this.b[n+1])));a.a+="]",r=a.a}return r},h.a=!1,h.c=!1,I(y2,"RegEx/RangeToken",138),D(592,1,{592:1},Ewe),h.a=0,I(y2,"RegEx/RegexParser/ReferencePosition",592),D(591,1,{3:1,591:1},LZe),h.Fb=function(t){var n;return t==null||!De(t,591)?!1:(n=l(t,591),vn(this.b,n.b)&&this.a==n.a)},h.Hb=function(){return s2(this.b+"/"+K9e(this.a))},h.Ib=function(){return this.c.Qm(this.a)},h.a=0,I(y2,"RegEx/RegularExpression",591),D(228,122,CT,ng),h.Km=function(){return this.a},h.Qm=function(t){var n,r,a;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:a="\\"+hae(this.a&Zs);break;case 12:a="\\f";break;case 10:a="\\n";break;case 13:a="\\r";break;case 9:a="\\t";break;case 27:a="\\e";break;default:this.a>=Io?(r=(n=this.a>>>0,"0"+n.toString(16)),a="\\v"+tf(r,r.length-6,r.length)):a=""+hae(this.a&Zs)}break;case 8:this==QPe||this==JPe?a=""+hae(this.a&Zs):a="\\"+hae(this.a&Zs);break;default:a=null}return a},h.a=0,I(y2,"RegEx/Token/CharToken",228),D(318,122,CT,Ty),h.Lm=function(t){return this.a},h.Nm=function(t){this.b=t},h.Om=function(t){this.c=t},h.Pm=function(){return 1},h.Qm=function(t){var n;if(this.e==3)if(this.c<0&&this.b<0)n=this.a.Qm(t)+"*";else if(this.c==this.b)n=this.a.Qm(t)+"{"+this.c+"}";else if(this.c>=0&&this.b>=0)n=this.a.Qm(t)+"{"+this.c+","+this.b+"}";else if(this.c>=0&&this.b<0)n=this.a.Qm(t)+"{"+this.c+",}";else throw ue(new Ac("Token#toString(): CLOSURE "+this.c+Co+this.b));else if(this.c<0&&this.b<0)n=this.a.Qm(t)+"*?";else if(this.c==this.b)n=this.a.Qm(t)+"{"+this.c+"}?";else if(this.c>=0&&this.b>=0)n=this.a.Qm(t)+"{"+this.c+","+this.b+"}?";else if(this.c>=0&&this.b<0)n=this.a.Qm(t)+"{"+this.c+",}?";else throw ue(new Ac("Token#toString(): NONGREEDYCLOSURE "+this.c+Co+this.b));return n},h.b=0,h.c=0,I(y2,"RegEx/Token/ClosureToken",318),D(837,122,CT,f5e),h.Lm=function(t){return t==0?this.a:this.b},h.Pm=function(){return 2},h.Qm=function(t){var n;return this.b.e==3&&this.b.Lm(0)==this.a?n=this.a.Qm(t)+"+":this.b.e==9&&this.b.Lm(0)==this.a?n=this.a.Qm(t)+"+?":n=this.a.Qm(t)+(""+this.b.Qm(t)),n},I(y2,"RegEx/Token/ConcatToken",837),D(1945,122,CT,Zlt),h.Lm=function(t){if(t==0)return this.d;if(t==1)return this.b;throw ue(new Ac("Internal Error: "+t))},h.Pm=function(){return this.b?2:1},h.Qm=function(t){var n;return this.c>0?n="(?("+this.c+")":this.a.e==8?n="(?("+this.a+")":n="(?"+this.a,this.b?n+=this.d+"|"+this.b+")":n+=this.d+")",n},h.c=0,I(y2,"RegEx/Token/ConditionToken",1945),D(1946,122,CT,Hot),h.Lm=function(t){return this.b},h.Pm=function(){return 1},h.Qm=function(t){return"(?"+(this.a==0?"":K9e(this.a))+(this.c==0?"":K9e(this.c))+":"+this.b.Qm(t)+")"},h.a=0,h.c=0,I(y2,"RegEx/Token/ModifierToken",1946),D(838,122,CT,k5e),h.Lm=function(t){return this.a},h.Pm=function(){return 1},h.Qm=function(t){var n;switch(n=null,this.e){case 6:this.b==0?n="(?:"+this.a.Qm(t)+")":n="("+this.a.Qm(t)+")";break;case 20:n="(?="+this.a.Qm(t)+")";break;case 21:n="(?!"+this.a.Qm(t)+")";break;case 22:n="(?<="+this.a.Qm(t)+")";break;case 23:n="(?"+this.a.Qm(t)+")"}return n},h.b=0,I(y2,"RegEx/Token/ParenToken",838),D(530,122,{3:1,122:1,530:1},coe),h.Mm=function(){return this.b},h.Qm=function(t){return this.e==12?"\\"+this.a:vTn(this.b)},h.a=0,I(y2,"RegEx/Token/StringToken",530),D(477,122,CT,B_),h.Jm=function(t){Qm(this,t)},h.Lm=function(t){return l(xw(this.a,t),122)},h.Pm=function(){return this.a?this.a.a.c.length:0},h.Qm=function(t){var n,r,a,o,f;if(this.e==1){if(this.a.a.c.length==2)n=l(xw(this.a,0),122),r=l(xw(this.a,1),122),r.e==3&&r.Lm(0)==n?o=n.Qm(t)+"+":r.e==9&&r.Lm(0)==n?o=n.Qm(t)+"+?":o=n.Qm(t)+(""+r.Qm(t));else{for(f=new Up,a=0;a=this.c.b:this.a<=this.c.b},h.Sb=function(){return this.b>0},h.Tb=function(){return this.b},h.Vb=function(){return this.b-1},h.Qb=function(){throw ue(new Hp(Z5t))},h.a=0,h.b=0,I(zSe,"ExclusiveRange/RangeIterator",258);var kf=Gk(GG,"C"),Vr=Gk(LL,"I"),ih=Gk(Cx,"Z"),nm=Gk(ML,"J"),Al=Gk(SL,"B"),Na=Gk(_L,"D"),B4=Gk(AL,"F"),h7=Gk(DL,"S"),FOn=ks("org.eclipse.elk.core.labels","ILabelManager"),nBe=ks(So,"DiagnosticChain"),rBe=ks(_5t,"ResourceSet"),iBe=I(So,"InvocationTargetException",null),MAt=(Hz(),Qmn),DAt=DAt=q8n;Vwn($cn),$wn("permProps",[[["locale","default"],[e6t,"gecko1_8"]],[["locale","default"],[e6t,"safari"]]]),DAt(null,"elk",null)}).call(this)}).call(this,typeof Ag<"u"?Ag:typeof self<"u"?self:typeof window<"u"?window:{})},{}],3:[function(u,d,p){function v(A,P){if(!(A instanceof P))throw new TypeError("Cannot call a class as a function")}function b(A,P){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return P&&(typeof P=="object"||typeof P=="function")?P:A}function y(A,P){if(typeof P!="function"&&P!==null)throw new TypeError("Super expression must either be null or a function, not "+typeof P);A.prototype=Object.create(P&&P.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),P&&(Object.setPrototypeOf?Object.setPrototypeOf(A,P):A.__proto__=P)}var T=u("./elk-api.js").default,_=function(A){y(P,A);function P(){var R=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};v(this,P);var F=Object.assign({},R),j=!1;try{u.resolve("web-worker"),j=!0}catch{}if(R.workerUrl)if(j){var K=u("web-worker");F.workerFactory=function(oe){return new K(oe)}}else console.warn(`Web worker requested but 'web-worker' package not installed. +Consider installing the package or pass your own 'workerFactory' to ELK's constructor. +... Falling back to non-web worker version.`);if(!F.workerFactory){var ee=u("./elk-worker.min.js"),ie=ee.Worker;F.workerFactory=function(oe){return new ie(oe)}}return b(this,(P.__proto__||Object.getPrototypeOf(P)).call(this,F))}return P}(T);Object.defineProperty(d.exports,"__esModule",{value:!0}),d.exports=_,_.default=_},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(u,d,p){d.exports=Worker},{}]},{},[3])(3)})})(HKe);var Can=HKe.exports;const San=hC(Can),VKe=new San;let Hv={};const _an={};let W7={};const Aan=async function(i,s,u,d,p,v,b){const T=u.select(`[id="${s}"]`).insert("g").attr("class","nodes"),_=Object.keys(i);return await Promise.all(_.map(async function(A){const P=i[A];let R="default";P.classes.length>0&&(R=P.classes.join(" ")),R=R+" flowchart-label";const F=om(P.styles);let j=P.text!==void 0?P.text:P.id;const K={width:0,height:0},ee=[{id:P.id+"-west",layoutOptions:{"port.side":"WEST"}},{id:P.id+"-east",layoutOptions:{"port.side":"EAST"}},{id:P.id+"-south",layoutOptions:{"port.side":"SOUTH"}},{id:P.id+"-north",layoutOptions:{"port.side":"NORTH"}}];let ie=0,oe="",pe={};switch(P.type){case"round":ie=5,oe="rect";break;case"square":oe="rect";break;case"diamond":oe="question",pe={portConstraints:"FIXED_SIDE"};break;case"hexagon":oe="hexagon";break;case"odd":oe="rect_left_inv_arrow";break;case"lean_right":oe="lean_right";break;case"lean_left":oe="lean_left";break;case"trapezoid":oe="trapezoid";break;case"inv_trapezoid":oe="inv_trapezoid";break;case"odd_right":oe="rect_left_inv_arrow";break;case"circle":oe="circle";break;case"ellipse":oe="ellipse";break;case"stadium":oe="stadium";break;case"subroutine":oe="subroutine";break;case"cylinder":oe="cylinder";break;case"group":oe="rect";break;case"doublecircle":oe="doublecircle";break;default:oe="rect"}const be={labelStyle:F.labelStyle,shape:oe,labelText:j,labelType:P.labelType,rx:ie,ry:ie,class:R,style:F.style,id:P.id,link:P.link,linkTarget:P.linkTarget,tooltip:p.db.getTooltip(P.id)||"",domId:p.db.lookUpDomId(P.id),haveCallback:P.haveCallback,width:P.type==="group"?500:void 0,dir:P.dir,type:P.type,props:P.props,padding:Vh().flowchart.padding};let ae,ne;if(be.type!=="group")ne=await tJ(T,be,P.dir),ae=ne.node().getBBox();else{d.createElementNS("http://www.w3.org/2000/svg","text");const{shapeSvg:de,bbox:X}=await g1(T,be,void 0,!0);K.width=X.width,K.wrappingWidth=Vh().flowchart.wrappingWidth,K.height=X.height,K.labelNode=de.node(),be.labelData=K}const se={id:P.id,ports:P.type==="diamond"?ee:[],layoutOptions:pe,labelText:j,labelData:K,domId:p.db.lookUpDomId(P.id),width:ae==null?void 0:ae.width,height:ae==null?void 0:ae.height,type:P.type,el:ne,parent:v.parentById[P.id]};W7[be.id]=se})),b},UKe=(i,s,u)=>{const d={TB:{in:{north:"north"},out:{south:"west",west:"east",east:"south"}},LR:{in:{west:"west"},out:{east:"south",south:"north",north:"east"}},RL:{in:{east:"east"},out:{west:"north",north:"south",south:"west"}},BT:{in:{south:"south"},out:{north:"east",east:"west",west:"north"}}};return d.TD=d.TB,d[u][s][i]},GKe=(i,s,u)=>{if(Xe.info("getNextPort",{node:i,edgeDirection:s,graphDirection:u}),!Hv[i])switch(u){case"TB":case"TD":Hv[i]={inPosition:"north",outPosition:"south"};break;case"BT":Hv[i]={inPosition:"south",outPosition:"north"};break;case"RL":Hv[i]={inPosition:"east",outPosition:"west"};break;case"LR":Hv[i]={inPosition:"west",outPosition:"east"};break}const d=s==="in"?Hv[i].inPosition:Hv[i].outPosition;return s==="in"?Hv[i].inPosition=UKe(Hv[i].inPosition,s,u):Hv[i].outPosition=UKe(Hv[i].outPosition,s,u),d},Lan=(i,s)=>{let u=i.start,d=i.end;const p=u,v=d,b=W7[u],y=W7[d];return!b||!y?{source:u,target:d}:(b.type==="diamond"&&(u=`${u}-${GKe(u,"out",s)}`),y.type==="diamond"&&(d=`${d}-${GKe(d,"in",s)}`),{source:u,target:d,sourceId:p,targetId:v})},Man=function(i,s,u,d){Xe.info("abc78 edges = ",i);const p=d.insert("g").attr("class","edgeLabels");let v={},b=s.db.getDirection(),y,T;if(i.defaultStyle!==void 0){const _=om(i.defaultStyle);y=_.style,T=_.labelStyle}return i.forEach(function(_){const A="L-"+_.start+"-"+_.end;v[A]===void 0?(v[A]=0,Xe.info("abc78 new entry",A,v[A])):(v[A]++,Xe.info("abc78 new entry",A,v[A]));let P=A+"-"+v[A];Xe.info("abc78 new link id to be used is",A,P,v[A]);const R="LS-"+_.start,F="LE-"+_.end,j={style:"",labelStyle:""};switch(j.minlen=_.length||1,_.type==="arrow_open"?j.arrowhead="none":j.arrowhead="normal",j.arrowTypeStart="arrow_open",j.arrowTypeEnd="arrow_open",_.type){case"double_arrow_cross":j.arrowTypeStart="arrow_cross";case"arrow_cross":j.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":j.arrowTypeStart="arrow_point";case"arrow_point":j.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":j.arrowTypeStart="arrow_circle";case"arrow_circle":j.arrowTypeEnd="arrow_circle";break}let K="",ee="";switch(_.stroke){case"normal":K="fill:none;",y!==void 0&&(K=y),T!==void 0&&(ee=T),j.thickness="normal",j.pattern="solid";break;case"dotted":j.thickness="normal",j.pattern="dotted",j.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":j.thickness="thick",j.pattern="solid",j.style="stroke-width: 3.5px;fill:none;";break}if(_.style!==void 0){const ne=om(_.style);K=ne.style,ee=ne.labelStyle}j.style=j.style+=K,j.labelStyle=j.labelStyle+=ee,_.interpolate!==void 0?j.curve=Ov(_.interpolate,kp):i.defaultInterpolate!==void 0?j.curve=Ov(i.defaultInterpolate,kp):j.curve=Ov(_an.curve,kp),_.text===void 0?_.style!==void 0&&(j.arrowheadStyle="fill: #333"):(j.arrowheadStyle="fill: #333",j.labelpos="c"),j.labelType=_.labelType,j.label=_.text.replace(ci.lineBreakRegex,` +`),_.style===void 0&&(j.style=j.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),j.labelStyle=j.labelStyle.replace("color:","fill:"),j.id=P,j.classes="flowchart-link "+R+" "+F;const ie=zme(p,j),{source:oe,target:pe,sourceId:be,targetId:ae}=Lan(_,b);Xe.debug("abc78 source and target",oe,pe),u.edges.push({id:"e"+_.start+_.end,sources:[oe],targets:[pe],sourceId:be,targetId:ae,labelEl:ie,labels:[{width:j.width,height:j.height,orgWidth:j.width,orgHeight:j.height,text:j.label,layoutOptions:{"edgeLabels.inline":"true","edgeLabels.placement":"CENTER"}}],edgeData:j})}),u},Dan=function(i,s,u,d,p){let v="";d&&(v=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,v=v.replace(/\(/g,"\\("),v=v.replace(/\)/g,"\\)")),AUe(i,s,v,p,u)},Ian=function(i,s){return Xe.info("Extracting classes"),s.db.getClasses()},Oan=function(i){const s={parentById:{},childrenById:{}},u=i.getSubGraphs();return Xe.info("Subgraphs - ",u),u.forEach(function(d){d.nodes.forEach(function(p){s.parentById[p]=d.id,s.childrenById[d.id]===void 0&&(s.childrenById[d.id]=[]),s.childrenById[d.id].push(p)})}),u.forEach(function(d){d.id,s.parentById[d.id]!==void 0&&s.parentById[d.id]}),s},Nan=function(i,s,u){const d=Tan(i,s,u);if(d===void 0||d==="root")return{x:0,y:0};const p=W7[d].offset;return{x:p.posX,y:p.posY}},Pan=function(i,s,u,d,p,v){const b=Nan(s.sourceId,s.targetId,p),y=s.sections[0].startPoint,T=s.sections[0].endPoint,A=(s.sections[0].bendPoints?s.sections[0].bendPoints:[]).map(pe=>[pe.x+b.x,pe.y+b.y]),P=[[y.x+b.x,y.y+b.y],...A,[T.x+b.x,T.y+b.y]],{x:R,y:F}=_Ue(s.edgeData),j=k7().x(R).y(F).curve(kp),K=i.insert("path").attr("d",j(P)).attr("class","path "+u.classes).attr("fill","none"),ee=i.insert("g").attr("class","edgeLabel"),ie=Ir(ee.node().appendChild(s.labelEl)),oe=ie.node().firstChild.getBoundingClientRect();ie.attr("width",oe.width),ie.attr("height",oe.height),ee.attr("transform",`translate(${s.labels[0].x+b.x}, ${s.labels[0].y+b.y})`),Dan(K,u,d.type,d.arrowMarkerAbsolute,v)},KKe=(i,s)=>{i.forEach(u=>{u.children||(u.children=[]);const d=s.childrenById[u.id];d&&d.forEach(p=>{u.children.push(W7[p])}),KKe(u.children,s)})},Ban=async function(i,s,u,d){var se;d.db.clear(),W7={},Hv={},d.db.setGen("gen-2"),d.parser.parse(i);const p=Ir("body").append("div").attr("style","height:400px").attr("id","cy");let v={id:"root",layoutOptions:{"elk.hierarchyHandling":"INCLUDE_CHILDREN","org.eclipse.elk.padding":"[top=100, left=100, bottom=110, right=110]","elk.layered.spacing.edgeNodeBetweenLayers":"30","elk.direction":"DOWN"},children:[],edges:[]};switch(Xe.info("Drawing flowchart using v3 renderer",VKe),d.db.getDirection()){case"BT":v.layoutOptions["elk.direction"]="UP";break;case"TB":v.layoutOptions["elk.direction"]="DOWN";break;case"LR":v.layoutOptions["elk.direction"]="RIGHT";break;case"RL":v.layoutOptions["elk.direction"]="LEFT";break}const{securityLevel:y,flowchart:T}=Vh();let _;y==="sandbox"&&(_=Ir("#i"+s));const A=Ir(y==="sandbox"?_.nodes()[0].contentDocument.body:"body"),P=y==="sandbox"?_.nodes()[0].contentDocument:document,R=A.select(`[id="${s}"]`);Sme(R,["point","circle","cross"],d.type,s);const j=d.db.getVertices();let K;const ee=d.db.getSubGraphs();Xe.info("Subgraphs - ",ee);for(let de=ee.length-1;de>=0;de--)K=ee[de],d.db.addVertex(K.id,{text:K.title,type:K.labelType},"group",void 0,K.classes,K.dir);const ie=R.insert("g").attr("class","subgraphs"),oe=Oan(d.db);v=await Aan(j,s,A,P,d,oe,v);const pe=R.insert("g").attr("class","edges edgePath"),be=d.db.getEdges();v=Man(be,d,v,R),Object.keys(W7).forEach(de=>{const X=W7[de];X.parent||v.children.push(X),oe.childrenById[de]!==void 0&&(X.labels=[{text:X.labelText,layoutOptions:{"nodeLabels.placement":"[H_CENTER, V_TOP, INSIDE]"},width:X.labelData.width,height:X.labelData.height}],delete X.x,delete X.y,delete X.width,delete X.height)}),KKe(v.children,oe),Xe.info("after layout",JSON.stringify(v,null,2));const ne=await VKe.layout(v);WKe(0,0,ne.children,R,ie,d,0),Xe.info("after layout",ne),(se=ne.edges)==null||se.map(de=>{Pan(pe,de,de.edgeData,d,oe,s)}),y9({},R,T.diagramPadding,T.useMaxWidth),p.remove()},WKe=(i,s,u,d,p,v,b)=>{u.forEach(function(y){if(y)if(W7[y.id].offset={posX:y.x+i,posY:y.y+s,x:i,y:s,depth:b,width:y.width,height:y.height},y.type==="group"){const T=p.insert("g").attr("class","subgraph");T.insert("rect").attr("class","subgraph subgraph-lvl-"+b%5+" node").attr("x",y.x+i).attr("y",y.y+s).attr("width",y.width).attr("height",y.height);const _=T.insert("g").attr("class","label"),A=Vh().flowchart.htmlLabels?y.labelData.width/2:0;_.attr("transform",`translate(${y.labels[0].x+i+y.x+A}, ${y.labels[0].y+s+y.y+3})`),_.node().appendChild(y.labelData.labelNode),Xe.info("Id (UGH)= ",y.type,y.labels)}else Xe.info("Id (UGH)= ",y.id),y.el.attr("transform",`translate(${y.x+i+y.width/2}, ${y.y+s+y.height/2})`)}),u.forEach(function(y){y&&y.type==="group"&&WKe(i+y.x,s+y.y,y.children,d,p,v,b+1)})},Fan={getClasses:Ian,draw:Ban},Ran=i=>{let s="";for(let u=0;u<5;u++)s+=` + .subgraph-lvl-${u} { + fill: ${i[`surface${u}`]}; + stroke: ${i[`surfacePeer${u}`]}; + } + `;return s},jan=Object.freeze(Object.defineProperty({__proto__:null,diagram:{db:_Ut,renderer:Fan,parser:Gbe,styles:i=>`.label { + font-family: ${i.fontFamily}; + color: ${i.nodeTextColor||i.textColor}; + } + .cluster-label text { + fill: ${i.titleColor}; + } + .cluster-label span { + color: ${i.titleColor}; + } + + .label text,span { + fill: ${i.nodeTextColor||i.textColor}; + color: ${i.nodeTextColor||i.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${i.mainBkg}; + stroke: ${i.nodeBorder}; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${i.arrowheadColor}; + } + + .edgePath .path { + stroke: ${i.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${i.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${i.edgeLabelBackground}; + rect { + opacity: 0.85; + background-color: ${i.edgeLabelBackground}; + fill: ${i.edgeLabelBackground}; + } + text-align: center; + } + + .cluster rect { + fill: ${i.clusterBkg}; + stroke: ${i.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${i.titleColor}; + } + + .cluster span { + color: ${i.titleColor}; + } + /* .cluster div { + color: ${i.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${i.fontFamily}; + font-size: 12px; + background: ${i.tertiaryColor}; + border: 1px solid ${i.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.textColor}; + } + .subgraph { + stroke-width:2; + rx:3; + } + // .subgraph-lvl-1 { + // fill:#ccc; + // // stroke:black; + // } + + .flowchart-label text { + text-anchor: middle; + } + + ${Ran(i)} +`}},Symbol.toStringTag,{value:"Module"}));var Qve=function(){var i=function(R,F,j,K){for(j=j||{},K=R.length;K--;j[R[K]]=F);return j},s=[6,8,10,11,12,14,16,17,20,21],u=[1,9],d=[1,10],p=[1,11],v=[1,12],b=[1,13],y=[1,16],T=[1,17],_={trace:function(){},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:function(F,j,K,ee,ie,oe,pe){var be=oe.length-1;switch(ie){case 1:return oe[be-1];case 2:this.$=[];break;case 3:oe[be-1].push(oe[be]),this.$=oe[be-1];break;case 4:case 5:this.$=oe[be];break;case 6:case 7:this.$=[];break;case 8:ee.getCommonDb().setDiagramTitle(oe[be].substr(6)),this.$=oe[be].substr(6);break;case 9:this.$=oe[be].trim(),ee.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=oe[be].trim(),ee.getCommonDb().setAccDescription(this.$);break;case 12:ee.addSection(oe[be].substr(8)),this.$=oe[be].substr(8);break;case 15:ee.addTask(oe[be],0,""),this.$=oe[be];break;case 16:ee.addEvent(oe[be].substr(2)),this.$=oe[be];break}},table:[{3:1,4:[1,2]},{1:[3]},i(s,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:u,12:d,14:p,16:v,17:b,18:14,19:15,20:y,21:T},i(s,[2,7],{1:[2,1]}),i(s,[2,3]),{9:18,11:u,12:d,14:p,16:v,17:b,18:14,19:15,20:y,21:T},i(s,[2,5]),i(s,[2,6]),i(s,[2,8]),{13:[1,19]},{15:[1,20]},i(s,[2,11]),i(s,[2,12]),i(s,[2,13]),i(s,[2,14]),i(s,[2,15]),i(s,[2,16]),i(s,[2,4]),i(s,[2,9]),i(s,[2,10])],defaultActions:{},parseError:function(F,j){if(j.recoverable)this.trace(F);else{var K=new Error(F);throw K.hash=j,K}},parse:function(F){var j=this,K=[0],ee=[],ie=[null],oe=[],pe=this.table,be="",ae=0,ne=0,se=2,de=1,X=oe.slice.call(arguments,1),ge=Object.create(this.lexer),W={yy:{}};for(var xe in this.yy)Object.prototype.hasOwnProperty.call(this.yy,xe)&&(W.yy[xe]=this.yy[xe]);ge.setInput(F,W.yy),W.yy.lexer=ge,W.yy.parser=this,typeof ge.yylloc>"u"&&(ge.yylloc={});var U=ge.yylloc;oe.push(U);var Fe=ge.options&&ge.options.ranges;typeof W.yy.parseError=="function"?this.parseError=W.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Pe(){var Et;return Et=ee.pop()||ge.lex()||de,typeof Et!="number"&&(Et instanceof Array&&(ee=Et,Et=ee.pop()),Et=j.symbols_[Et]||Et),Et}for(var je,Ie,Se,Ce,ke={},Ke,Ft,Ne,gn;;){if(Ie=K[K.length-1],this.defaultActions[Ie]?Se=this.defaultActions[Ie]:((je===null||typeof je>"u")&&(je=Pe()),Se=pe[Ie]&&pe[Ie][je]),typeof Se>"u"||!Se.length||!Se[0]){var _t="";gn=[];for(Ke in pe[Ie])this.terminals_[Ke]&&Ke>se&&gn.push("'"+this.terminals_[Ke]+"'");ge.showPosition?_t="Parse error on line "+(ae+1)+`: +`+ge.showPosition()+` +Expecting `+gn.join(", ")+", got '"+(this.terminals_[je]||je)+"'":_t="Parse error on line "+(ae+1)+": Unexpected "+(je==de?"end of input":"'"+(this.terminals_[je]||je)+"'"),this.parseError(_t,{text:ge.match,token:this.terminals_[je]||je,line:ge.yylineno,loc:U,expected:gn})}if(Se[0]instanceof Array&&Se.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Ie+", token: "+je);switch(Se[0]){case 1:K.push(je),ie.push(ge.yytext),oe.push(ge.yylloc),K.push(Se[1]),je=null,ne=ge.yyleng,be=ge.yytext,ae=ge.yylineno,U=ge.yylloc;break;case 2:if(Ft=this.productions_[Se[1]][1],ke.$=ie[ie.length-Ft],ke._$={first_line:oe[oe.length-(Ft||1)].first_line,last_line:oe[oe.length-1].last_line,first_column:oe[oe.length-(Ft||1)].first_column,last_column:oe[oe.length-1].last_column},Fe&&(ke._$.range=[oe[oe.length-(Ft||1)].range[0],oe[oe.length-1].range[1]]),Ce=this.performAction.apply(ke,[be,ne,ae,W.yy,Se[1],ie,oe].concat(X)),typeof Ce<"u")return Ce;Ft&&(K=K.slice(0,-1*Ft*2),ie=ie.slice(0,-1*Ft),oe=oe.slice(0,-1*Ft)),K.push(this.productions_[Se[1]][0]),ie.push(ke.$),oe.push(ke._$),Ne=pe[K[K.length-2]][K[K.length-1]],K.push(Ne);break;case 3:return!0}}return!0}},A=function(){var R={EOF:1,parseError:function(j,K){if(this.yy.parser)this.yy.parser.parseError(j,K);else throw new Error(j)},setInput:function(F,j){return this.yy=j||this.yy||{},this._input=F,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},input:function(){var F=this._input[0];this.yytext+=F,this.yyleng++,this.offset++,this.match+=F,this.matched+=F;var j=F.match(/(?:\r\n?|\n).*/g);return j?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),F},unput:function(F){var j=F.length,K=F.split(/(?:\r\n?|\n)/g);this._input=F+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-j),this.offset-=j;var ee=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),K.length-1&&(this.yylineno-=K.length-1);var ie=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:K?(K.length===ee.length?this.yylloc.first_column:0)+ee[ee.length-K.length].length-K[0].length:this.yylloc.first_column-j},this.options.ranges&&(this.yylloc.range=[ie[0],ie[0]+this.yyleng-j]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(F){this.unput(this.match.slice(F))},pastInput:function(){var F=this.matched.substr(0,this.matched.length-this.match.length);return(F.length>20?"...":"")+F.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var F=this.match;return F.length<20&&(F+=this._input.substr(0,20-F.length)),(F.substr(0,20)+(F.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var F=this.pastInput(),j=new Array(F.length+1).join("-");return F+this.upcomingInput()+` +`+j+"^"},test_match:function(F,j){var K,ee,ie;if(this.options.backtrack_lexer&&(ie={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&&(ie.yylloc.range=this.yylloc.range.slice(0))),ee=F[0].match(/(?:\r\n?|\n).*/g),ee&&(this.yylineno+=ee.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:ee?ee[ee.length-1].length-ee[ee.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+F[0].length},this.yytext+=F[0],this.match+=F[0],this.matches=F,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(F[0].length),this.matched+=F[0],K=this.performAction.call(this,this.yy,this,j,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),K)return K;if(this._backtrack){for(var oe in ie)this[oe]=ie[oe];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var F,j,K,ee;this._more||(this.yytext="",this.match="");for(var ie=this._currentRules(),oe=0;oej[0].length)){if(j=K,ee=oe,this.options.backtrack_lexer){if(F=this.test_match(K,ie[oe]),F!==!1)return F;if(this._backtrack){j=!1;continue}else return!1}else if(!this.options.flex)break}return j?(F=this.test_match(j,ie[ee]),F!==!1?F:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var j=this.next();return j||this.lex()},begin:function(j){this.conditionStack.push(j)},popState:function(){var j=this.conditionStack.length-1;return j>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(j){return j=this.conditionStack.length-1-Math.abs(j||0),j>=0?this.conditionStack[j]:"INITIAL"},pushState:function(j){this.begin(j)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(j,K,ee,ie){switch(ee){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;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";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"}},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 R}();_.lexer=A;function P(){this.yy={}}return P.prototype=_,_.Parser=P,new P}();Qve.parser=Qve;const $an=Qve;let ZD="",YKe=0;const Jve=[],IJ=[],eI=[],XKe=()=>Jje,QKe=function(){Jve.length=0,IJ.length=0,ZD="",eI.length=0,Pg()},JKe=function(i){ZD=i,Jve.push(i)},ZKe=function(){return Jve},eWe=function(){let i=iWe();const s=100;let u=0;for(;!i&&uu.id===YKe-1).events.push(i)},rWe=function(i){const s={section:ZD,type:ZD,description:i,task:i,classes:[]};IJ.push(s)},iWe=function(){const i=function(u){return eI[u].processed};let s=!0;for(const[u,d]of eI.entries())i(u),s=s&&d.processed;return s},zan=Object.freeze(Object.defineProperty({__proto__:null,addEvent:nWe,addSection:JKe,addTask:tWe,addTaskOrg:rWe,clear:QKe,default:{clear:QKe,getCommonDb:XKe,addSection:JKe,getSections:ZKe,getTasks:eWe,addTask:tWe,addTaskOrg:rWe,addEvent:nWe},getCommonDb:XKe,getSections:ZKe,getTasks:eWe},Symbol.toStringTag,{value:"Module"})),qan=12,OJ=function(i,s){const u=i.append("rect");return u.attr("x",s.x),u.attr("y",s.y),u.attr("fill",s.fill),u.attr("stroke",s.stroke),u.attr("width",s.width),u.attr("height",s.height),u.attr("rx",s.rx),u.attr("ry",s.ry),s.class!==void 0&&u.attr("class",s.class),u},Han=function(i,s){const d=i.append("circle").attr("cx",s.cx).attr("cy",s.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),p=i.append("g");p.append("circle").attr("cx",s.cx-15/3).attr("cy",s.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),p.append("circle").attr("cx",s.cx+15/3).attr("cy",s.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function v(T){const _=lD().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);T.append("path").attr("class","mouth").attr("d",_).attr("transform","translate("+s.cx+","+(s.cy+2)+")")}function b(T){const _=lD().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);T.append("path").attr("class","mouth").attr("d",_).attr("transform","translate("+s.cx+","+(s.cy+7)+")")}function y(T){T.append("line").attr("class","mouth").attr("stroke",2).attr("x1",s.cx-5).attr("y1",s.cy+7).attr("x2",s.cx+5).attr("y2",s.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return s.score>3?v(p):s.score<3?b(p):y(p),d},Van=function(i,s){const u=i.append("circle");return u.attr("cx",s.cx),u.attr("cy",s.cy),u.attr("class","actor-"+s.pos),u.attr("fill",s.fill),u.attr("stroke",s.stroke),u.attr("r",s.r),u.class!==void 0&&u.attr("class",u.class),s.title!==void 0&&u.append("title").text(s.title),u},sWe=function(i,s){const u=s.text.replace(//gi," "),d=i.append("text");d.attr("x",s.x),d.attr("y",s.y),d.attr("class","legend"),d.style("text-anchor",s.anchor),s.class!==void 0&&d.attr("class",s.class);const p=d.append("tspan");return p.attr("x",s.x+s.textMargin*2),p.text(u),d},Uan=function(i,s){function u(p,v,b,y,T){return p+","+v+" "+(p+b)+","+v+" "+(p+b)+","+(v+y-T)+" "+(p+b-T*1.2)+","+(v+y)+" "+p+","+(v+y)}const d=i.append("polygon");d.attr("points",u(s.x,s.y,50,20,7)),d.attr("class","labelBox"),s.y=s.y+s.labelMargin,s.x=s.x+.5*s.labelMargin,sWe(i,s)},Gan=function(i,s,u){const d=i.append("g"),p=Zve();p.x=s.x,p.y=s.y,p.fill=s.fill,p.width=u.width,p.height=u.height,p.class="journey-section section-type-"+s.num,p.rx=3,p.ry=3,OJ(d,p),oWe(u)(s.text,d,p.x,p.y,p.width,p.height,{class:"journey-section section-type-"+s.num},u,s.colour)};let aWe=-1;const Kan=function(i,s,u){const d=s.x+u.width/2,p=i.append("g");aWe++;const v=300+5*30;p.append("line").attr("id","task"+aWe).attr("x1",d).attr("y1",s.y).attr("x2",d).attr("y2",v).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),Han(p,{cx:d,cy:300+(5-s.score)*30,score:s.score});const b=Zve();b.x=s.x,b.y=s.y,b.fill=s.fill,b.width=u.width,b.height=u.height,b.class="task task-type-"+s.num,b.rx=3,b.ry=3,OJ(p,b),s.x+14,oWe(u)(s.task,p,b.x,b.y,b.width,b.height,{class:"task"},u,s.colour)},Wan=function(i,s){OJ(i,{x:s.startx,y:s.starty,width:s.stopx-s.startx,height:s.stopy-s.starty,fill:s.fill,class:"rect"}).lower()},Yan=function(){return{x:0,y:0,fill:void 0,"text-anchor":"start",width:100,height:100,textMargin:0,rx:0,ry:0}},Zve=function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}},oWe=function(){function i(p,v,b,y,T,_,A,P){const R=v.append("text").attr("x",b+T/2).attr("y",y+_/2+5).style("font-color",P).style("text-anchor","middle").text(p);d(R,A)}function s(p,v,b,y,T,_,A,P,R){const{taskFontSize:F,taskFontFamily:j}=P,K=p.split(//gi);for(let ee=0;ee)/).reverse(),p,v=[],b=1.1,y=u.attr("y"),T=parseFloat(u.attr("dy")),_=u.text(null).append("tspan").attr("x",0).attr("y",y).attr("dy",T+"em");for(let A=0;As||p==="
")&&(v.pop(),_.text(v.join(" ").trim()),p==="
"?v=[""]:v=[p],_=u.append("tspan").attr("x",0).attr("y",y).attr("dy",b+"em").text(p))})}const Qan=function(i,s,u,d){const p=u%qan-1,v=i.append("g");s.section=p,v.attr("class",(s.class?s.class+" ":"")+"timeline-node "+("section-"+p));const b=v.append("g"),y=v.append("g"),_=y.append("text").text(s.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(cWe,s.width).node().getBBox(),A=d.fontSize&&d.fontSize.replace?d.fontSize.replace("px",""):d.fontSize;return s.height=_.height+A*1.1*.5+s.padding,s.height=Math.max(s.height,s.maxHeight),s.width=s.width+2*s.padding,y.attr("transform","translate("+s.width/2+", "+s.padding/2+")"),Zan(b,s,p),s},Jan=function(i,s,u){const d=i.append("g"),v=d.append("text").text(s.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(cWe,s.width).node().getBBox(),b=u.fontSize&&u.fontSize.replace?u.fontSize.replace("px",""):u.fontSize;return d.remove(),v.height+b*1.1*.5+s.padding},Zan=function(i,s,u){i.append("path").attr("id","node-"+s.id).attr("class","node-bkg node-"+s.type).attr("d",`M0 ${s.height-5} v${-s.height+2*5} q0,-5 5,-5 h${s.width-2*5} q5,0 5,5 v${s.height-5} H0 Z`),i.append("line").attr("class","node-line-"+u).attr("x1",0).attr("y1",s.height).attr("x2",s.width).attr("y2",s.height)},sS={drawRect:OJ,drawCircle:Van,drawSection:Gan,drawText:sWe,drawLabel:Uan,drawTask:Kan,drawBackgroundRect:Wan,getTextObj:Yan,getNoteRect:Zve,initGraphics:Xan,drawNode:Qan,getVirtualNodeHeight:Jan},eon=function(i,s,u,d){var X,ge;const p=qt(),v=p.leftMargin??50;Xe.debug("timeline",d.db);const b=p.securityLevel;let y;b==="sandbox"&&(y=Ir("#i"+s));const _=Ir(b==="sandbox"?y.nodes()[0].contentDocument.body:"body").select("#"+s);_.append("g");const A=d.db.getTasks(),P=d.db.getCommonDb().getDiagramTitle();Xe.debug("task",A),sS.initGraphics(_);const R=d.db.getSections();Xe.debug("sections",R);let F=0,j=0,K=0,ee=0,ie=50+v,oe=50;ee=50;let pe=0,be=!0;R.forEach(function(W){const xe={number:pe,descr:W,section:pe,width:150,padding:20,maxHeight:F},U=sS.getVirtualNodeHeight(_,xe,p);Xe.debug("sectionHeight before draw",U),F=Math.max(F,U+20)});let ae=0,ne=0;Xe.debug("tasks.length",A.length);for(const[W,xe]of A.entries()){const U={number:W,descr:xe,section:xe.section,width:150,padding:20,maxHeight:j},Fe=sS.getVirtualNodeHeight(_,U,p);Xe.debug("taskHeight before draw",Fe),j=Math.max(j,Fe+20),ae=Math.max(ae,xe.events.length);let Pe=0;for(let je=0;je0?R.forEach(W=>{const xe=A.filter(je=>je.section===W),U={number:pe,descr:W,section:pe,width:200*Math.max(xe.length,1)-50,padding:20,maxHeight:F};Xe.debug("sectionNode",U);const Fe=_.append("g"),Pe=sS.drawNode(Fe,U,pe,p);Xe.debug("sectionNode output",Pe),Fe.attr("transform",`translate(${ie}, ${ee})`),oe+=F+50,xe.length>0&&uWe(_,xe,pe,ie,oe,j,p,ae,ne,F,!1),ie+=200*Math.max(xe.length,1),oe=ee,pe++}):(be=!1,uWe(_,A,pe,ie,oe,j,p,ae,ne,F,!0));const se=_.node().getBBox();Xe.debug("bounds",se),P&&_.append("text").text(P).attr("x",se.width/2-v).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),K=be?F+j+150:j+100,_.append("g").attr("class","lineWrapper").append("line").attr("x1",v).attr("y1",K).attr("x2",se.width+3*v).attr("y2",K).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),y9(void 0,_,((X=p.timeline)==null?void 0:X.padding)??50,((ge=p.timeline)==null?void 0:ge.useMaxWidth)??!1)},uWe=function(i,s,u,d,p,v,b,y,T,_,A){var P;for(const R of s){const F={descr:R.task,section:u,number:u,width:150,padding:20,maxHeight:v};Xe.debug("taskNode",F);const j=i.append("g").attr("class","taskWrapper"),ee=sS.drawNode(j,F,u,b).height;if(Xe.debug("taskHeight after draw",ee),j.attr("transform",`translate(${d}, ${p})`),v=Math.max(v,ee),R.events){const ie=i.append("g").attr("class","lineWrapper");let oe=v;p+=100,oe=oe+ton(i,R.events,u,d,p,b),p-=100,ie.append("line").attr("x1",d+190/2).attr("y1",p+v).attr("x2",d+190/2).attr("y2",p+v+(A?v:_)+T+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}d=d+200,A&&!((P=b.timeline)!=null&&P.disableMulticolor)&&u++}p=p-10},ton=function(i,s,u,d,p,v){let b=0;const y=p;p=p+100;for(const T of s){const _={descr:T,section:u,number:u,width:150,padding:20,maxHeight:50};Xe.debug("eventNode",_);const A=i.append("g").attr("class","eventWrapper"),R=sS.drawNode(A,_,u,v).height;b=b+R,A.attr("transform",`translate(${d}, ${p})`),p=p+10+R}return p=y,b},non={setConf:()=>{},draw:eon},ron=i=>{let s="";for(let u=0;u` + .edge { + stroke-width: 3; + } + ${ron(i)} + .section-root rect, .section-root path, .section-root circle { + fill: ${i.git0}; + } + .section-root text { + fill: ${i.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .eventWrapper { + filter: brightness(120%); + } +`}},Symbol.toStringTag,{value:"Module"}));var ewe=function(){var i=function(be,ae,ne,se){for(ne=ne||{},se=be.length;se--;ne[be[se]]=ae);return ne},s=[1,4],u=[1,13],d=[1,12],p=[1,15],v=[1,16],b=[1,20],y=[1,19],T=[6,7,8],_=[1,26],A=[1,24],P=[1,25],R=[6,7,11],F=[1,6,13,15,16,19,22],j=[1,33],K=[1,34],ee=[1,6,7,11,13,15,16,19,22],ie={trace:function(){},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:function(ae,ne,se,de,X,ge,W){var xe=ge.length-1;switch(X){case 6:case 7:return de;case 8:de.getLogger().trace("Stop NL ");break;case 9:de.getLogger().trace("Stop EOF ");break;case 11:de.getLogger().trace("Stop NL2 ");break;case 12:de.getLogger().trace("Stop EOF2 ");break;case 15:de.getLogger().info("Node: ",ge[xe].id),de.addNode(ge[xe-1].length,ge[xe].id,ge[xe].descr,ge[xe].type);break;case 16:de.getLogger().trace("Icon: ",ge[xe]),de.decorateNode({icon:ge[xe]});break;case 17:case 21:de.decorateNode({class:ge[xe]});break;case 18:de.getLogger().trace("SPACELIST");break;case 19:de.getLogger().trace("Node: ",ge[xe].id),de.addNode(0,ge[xe].id,ge[xe].descr,ge[xe].type);break;case 20:de.decorateNode({icon:ge[xe]});break;case 25:de.getLogger().trace("node found ..",ge[xe-2]),this.$={id:ge[xe-1],descr:ge[xe-1],type:de.getType(ge[xe-2],ge[xe])};break;case 26:this.$={id:ge[xe],descr:ge[xe],type:de.nodeType.DEFAULT};break;case 27:de.getLogger().trace("node found ..",ge[xe-3]),this.$={id:ge[xe-3],descr:ge[xe-1],type:de.getType(ge[xe-2],ge[xe])};break}},table:[{3:1,4:2,5:3,6:[1,5],8:s},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:s},{6:u,7:[1,10],9:9,12:11,13:d,14:14,15:p,16:v,17:17,18:18,19:b,22:y},i(T,[2,3]),{1:[2,2]},i(T,[2,4]),i(T,[2,5]),{1:[2,6],6:u,12:21,13:d,14:14,15:p,16:v,17:17,18:18,19:b,22:y},{6:u,9:22,12:11,13:d,14:14,15:p,16:v,17:17,18:18,19:b,22:y},{6:_,7:A,10:23,11:P},i(R,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:b,22:y}),i(R,[2,18]),i(R,[2,19]),i(R,[2,20]),i(R,[2,21]),i(R,[2,23]),i(R,[2,24]),i(R,[2,26],{19:[1,30]}),{20:[1,31]},{6:_,7:A,10:32,11:P},{1:[2,7],6:u,12:21,13:d,14:14,15:p,16:v,17:17,18:18,19:b,22:y},i(F,[2,14],{7:j,11:K}),i(ee,[2,8]),i(ee,[2,9]),i(ee,[2,10]),i(R,[2,15]),i(R,[2,16]),i(R,[2,17]),{20:[1,35]},{21:[1,36]},i(F,[2,13],{7:j,11:K}),i(ee,[2,11]),i(ee,[2,12]),{21:[1,37]},i(R,[2,25]),i(R,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:function(ae,ne){if(ne.recoverable)this.trace(ae);else{var se=new Error(ae);throw se.hash=ne,se}},parse:function(ae){var ne=this,se=[0],de=[],X=[null],ge=[],W=this.table,xe="",U=0,Fe=0,Pe=2,je=1,Ie=ge.slice.call(arguments,1),Se=Object.create(this.lexer),Ce={yy:{}};for(var ke in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ke)&&(Ce.yy[ke]=this.yy[ke]);Se.setInput(ae,Ce.yy),Ce.yy.lexer=Se,Ce.yy.parser=this,typeof Se.yylloc>"u"&&(Se.yylloc={});var Ke=Se.yylloc;ge.push(Ke);var Ft=Se.options&&Se.options.ranges;typeof Ce.yy.parseError=="function"?this.parseError=Ce.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ne(){var On;return On=de.pop()||Se.lex()||je,typeof On!="number"&&(On instanceof Array&&(de=On,On=de.pop()),On=ne.symbols_[On]||On),On}for(var gn,_t,Et,Gt,ln={},xt,Pt,Qe,Dt;;){if(_t=se[se.length-1],this.defaultActions[_t]?Et=this.defaultActions[_t]:((gn===null||typeof gn>"u")&&(gn=Ne()),Et=W[_t]&&W[_t][gn]),typeof Et>"u"||!Et.length||!Et[0]){var kt="";Dt=[];for(xt in W[_t])this.terminals_[xt]&&xt>Pe&&Dt.push("'"+this.terminals_[xt]+"'");Se.showPosition?kt="Parse error on line "+(U+1)+`: +`+Se.showPosition()+` +Expecting `+Dt.join(", ")+", got '"+(this.terminals_[gn]||gn)+"'":kt="Parse error on line "+(U+1)+": Unexpected "+(gn==je?"end of input":"'"+(this.terminals_[gn]||gn)+"'"),this.parseError(kt,{text:Se.match,token:this.terminals_[gn]||gn,line:Se.yylineno,loc:Ke,expected:Dt})}if(Et[0]instanceof Array&&Et.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_t+", token: "+gn);switch(Et[0]){case 1:se.push(gn),X.push(Se.yytext),ge.push(Se.yylloc),se.push(Et[1]),gn=null,Fe=Se.yyleng,xe=Se.yytext,U=Se.yylineno,Ke=Se.yylloc;break;case 2:if(Pt=this.productions_[Et[1]][1],ln.$=X[X.length-Pt],ln._$={first_line:ge[ge.length-(Pt||1)].first_line,last_line:ge[ge.length-1].last_line,first_column:ge[ge.length-(Pt||1)].first_column,last_column:ge[ge.length-1].last_column},Ft&&(ln._$.range=[ge[ge.length-(Pt||1)].range[0],ge[ge.length-1].range[1]]),Gt=this.performAction.apply(ln,[xe,Fe,U,Ce.yy,Et[1],X,ge].concat(Ie)),typeof Gt<"u")return Gt;Pt&&(se=se.slice(0,-1*Pt*2),X=X.slice(0,-1*Pt),ge=ge.slice(0,-1*Pt)),se.push(this.productions_[Et[1]][0]),X.push(ln.$),ge.push(ln._$),Qe=W[se[se.length-2]][se[se.length-1]],se.push(Qe);break;case 3:return!0}}return!0}},oe=function(){var be={EOF:1,parseError:function(ne,se){if(this.yy.parser)this.yy.parser.parseError(ne,se);else throw new Error(ne)},setInput:function(ae,ne){return this.yy=ne||this.yy||{},this._input=ae,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},input:function(){var ae=this._input[0];this.yytext+=ae,this.yyleng++,this.offset++,this.match+=ae,this.matched+=ae;var ne=ae.match(/(?:\r\n?|\n).*/g);return ne?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),ae},unput:function(ae){var ne=ae.length,se=ae.split(/(?:\r\n?|\n)/g);this._input=ae+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-ne),this.offset-=ne;var de=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),se.length-1&&(this.yylineno-=se.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:se?(se.length===de.length?this.yylloc.first_column:0)+de[de.length-se.length].length-se[0].length:this.yylloc.first_column-ne},this.options.ranges&&(this.yylloc.range=[X[0],X[0]+this.yyleng-ne]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(ae){this.unput(this.match.slice(ae))},pastInput:function(){var ae=this.matched.substr(0,this.matched.length-this.match.length);return(ae.length>20?"...":"")+ae.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var ae=this.match;return ae.length<20&&(ae+=this._input.substr(0,20-ae.length)),(ae.substr(0,20)+(ae.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var ae=this.pastInput(),ne=new Array(ae.length+1).join("-");return ae+this.upcomingInput()+` +`+ne+"^"},test_match:function(ae,ne){var se,de,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))),de=ae[0].match(/(?:\r\n?|\n).*/g),de&&(this.yylineno+=de.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:de?de[de.length-1].length-de[de.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+ae[0].length},this.yytext+=ae[0],this.match+=ae[0],this.matches=ae,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(ae[0].length),this.matched+=ae[0],se=this.performAction.call(this,this.yy,this,ne,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),se)return se;if(this._backtrack){for(var ge in X)this[ge]=X[ge];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var ae,ne,se,de;this._more||(this.yytext="",this.match="");for(var X=this._currentRules(),ge=0;gene[0].length)){if(ne=se,de=ge,this.options.backtrack_lexer){if(ae=this.test_match(se,X[ge]),ae!==!1)return ae;if(this._backtrack){ne=!1;continue}else return!1}else if(!this.options.flex)break}return ne?(ae=this.test_match(ne,X[de]),ae!==!1?ae:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var ne=this.next();return ne||this.lex()},begin:function(ne){this.conditionStack.push(ne)},popState:function(){var ne=this.conditionStack.length-1;return ne>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(ne){return ne=this.conditionStack.length-1-Math.abs(ne||0),ne>=0?this.conditionStack[ne]:"INITIAL"},pushState:function(ne){this.begin(ne)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(ne,se,de,X){switch(de){case 0:return ne.getLogger().trace("Found comment",se.yytext),6;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;case 4:this.popState();break;case 5:ne.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return ne.getLogger().trace("SPACELINE"),6;case 7:return 7;case 8:return 15;case 9:ne.getLogger().trace("end icon"),this.popState();break;case 10:return ne.getLogger().trace("Exploding node"),this.begin("NODE"),19;case 11:return ne.getLogger().trace("Cloud"),this.begin("NODE"),19;case 12:return ne.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;case 13:return ne.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;case 14:return this.begin("NODE"),19;case 15:return this.begin("NODE"),19;case 16:return this.begin("NODE"),19;case 17:return this.begin("NODE"),19;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:ne.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return ne.getLogger().trace("description:",se.yytext),"NODE_DESCR";case 26:this.popState();break;case 27:return this.popState(),ne.getLogger().trace("node end ))"),"NODE_DEND";case 28:return this.popState(),ne.getLogger().trace("node end )"),"NODE_DEND";case 29:return this.popState(),ne.getLogger().trace("node end ...",se.yytext),"NODE_DEND";case 30:return this.popState(),ne.getLogger().trace("node end (("),"NODE_DEND";case 31:return this.popState(),ne.getLogger().trace("node end (-"),"NODE_DEND";case 32:return this.popState(),ne.getLogger().trace("node end (-"),"NODE_DEND";case 33:return this.popState(),ne.getLogger().trace("node end (("),"NODE_DEND";case 34:return this.popState(),ne.getLogger().trace("node end (("),"NODE_DEND";case 35:return ne.getLogger().trace("Long description:",se.yytext),20;case 36:return ne.getLogger().trace("Long description:",se.yytext),20}},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 be}();ie.lexer=oe;function pe(){this.yy={}}return pe.prototype=ie,ie.Parser=pe,new pe}();ewe.parser=ewe;const son=ewe;let K3=[],lWe=0,twe={};const aon=()=>{K3=[],lWe=0,twe={}},oon=function(i){for(let s=K3.length-1;s>=0;s--)if(K3[s].levelK3.length>0?K3[0]:null,uon=(i,s,u,d)=>{var T,_;Xe.info("addNode",i,s,u,d);const p=qt();let v=((T=p.mindmap)==null?void 0:T.padding)??sh.mindmap.padding;switch(d){case v1.ROUNDED_RECT:case v1.RECT:case v1.HEXAGON:v*=2}const b={id:lWe++,nodeId:Yf(s,p),level:i,descr:Yf(u,p),type:d,children:[],width:((_=p.mindmap)==null?void 0:_.maxNodeWidth)??sh.mindmap.maxNodeWidth,padding:v},y=oon(i);if(y)y.children.push(b),K3.push(b);else if(K3.length===0)K3.push(b);else throw new Error('There can be only one root. No parent could be found for ("'+b.descr+'")')},v1={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},lon={clear:aon,addNode:uon,getMindmap:con,nodeType:v1,getType:(i,s)=>{switch(Xe.debug("In get type",i,s),i){case"[":return v1.RECT;case"(":return s===")"?v1.ROUNDED_RECT:v1.CLOUD;case"((":return v1.CIRCLE;case")":return v1.CLOUD;case"))":return v1.BANG;case"{{":return v1.HEXAGON;default:return v1.DEFAULT}},setElementForId:(i,s)=>{twe[i]=s},decorateNode:i=>{if(!i)return;const s=qt(),u=K3[K3.length-1];i.icon&&(u.icon=Yf(i.icon,s)),i.class&&(u.class=Yf(i.class,s))},type2Str:i=>{switch(i){case v1.DEFAULT:return"no-border";case v1.RECT:return"rect";case v1.ROUNDED_RECT:return"rounded-rect";case v1.CIRCLE:return"circle";case v1.CLOUD:return"cloud";case v1.BANG:return"bang";case v1.HEXAGON:return"hexgon";default:return"no-border"}},getLogger:()=>Xe,getElementById:i=>twe[i]};var hWe={exports:{}};(function(i,s){(function(u,d){i.exports=d()})(Ag,function(){function u(x){"@babel/helpers - typeof";return u=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(m){return typeof m}:function(m){return m&&typeof Symbol=="function"&&m.constructor===Symbol&&m!==Symbol.prototype?"symbol":typeof m},u(x)}function d(x,m){if(!(x instanceof m))throw new TypeError("Cannot call a class as a function")}function p(x,m){for(var k=0;kx.length)&&(m=x.length);for(var k=0,S=new Array(m);k"u"?null:window,j=F?F.navigator:null;F&&F.document;var K=u(""),ee=u({}),ie=u(function(){}),oe=typeof HTMLElement>"u"?"undefined":u(HTMLElement),pe=function(m){return m&&m.instanceString&&ae(m.instanceString)?m.instanceString():null},be=function(m){return m!=null&&u(m)==K},ae=function(m){return m!=null&&u(m)===ie},ne=function(m){return!xe(m)&&(Array.isArray?Array.isArray(m):m!=null&&m instanceof Array)},se=function(m){return m!=null&&u(m)===ee&&!ne(m)&&m.constructor===Object},de=function(m){return m!=null&&u(m)===ee},X=function(m){return m!=null&&u(m)===u(1)&&!isNaN(m)},ge=function(m){return X(m)&&Math.floor(m)===m},W=function(m){if(oe!=="undefined")return m!=null&&m instanceof HTMLElement},xe=function(m){return U(m)||Fe(m)},U=function(m){return pe(m)==="collection"&&m._private.single},Fe=function(m){return pe(m)==="collection"&&!m._private.single},Pe=function(m){return pe(m)==="core"},je=function(m){return pe(m)==="stylesheet"},Ie=function(m){return pe(m)==="event"},Se=function(m){return m==null?!0:!!(m===""||m.match(/^\s+$/))},Ce=function(m){return typeof HTMLElement>"u"?!1:m instanceof HTMLElement},ke=function(m){return se(m)&&X(m.x1)&&X(m.x2)&&X(m.y1)&&X(m.y2)},Ke=function(m){return de(m)&&ae(m.then)},Ft=function(){return j&&j.userAgent.match(/msie|trident|edge/i)},Ne=function(m,k){k||(k=function(){if(arguments.length===1)return arguments[0];if(arguments.length===0)return"undefined";for(var O=[],N=0;Nk?1:0},zr=function(m,k){return-1*ht(m,k)},yt=Object.assign!=null?Object.assign.bind(Object):function(x){for(var m=arguments,k=1;k1&&(_e-=1),_e<1/6?me+(Le-me)*6*_e:_e<1/2?Le:_e<2/3?me+(Le-me)*(2/3-_e)*6:me}var Z=new RegExp("^"+Qe+"$").exec(m);if(Z){if(S=parseInt(Z[1]),S<0?S=(360- -1*S%360)%360:S>360&&(S=S%360),S/=360,M=parseFloat(Z[2]),M<0||M>100||(M=M/100,O=parseFloat(Z[3]),O<0||O>100)||(O=O/100,N=Z[4],N!==void 0&&(N=parseFloat(N),N<0||N>1)))return;if(M===0)$=H=q=Math.round(O*255);else{var ce=O<.5?O*(1+M):O+M-O*M,ve=2*O-ce;$=Math.round(255*Y(ve,ce,S+1/3)),H=Math.round(255*Y(ve,ce,S)),q=Math.round(255*Y(ve,ce,S-1/3))}k=[$,H,q,N]}return k},Ma=function(m){var k,S=new RegExp("^"+xt+"$").exec(m);if(S){k=[];for(var M=[],O=1;O<=3;O++){var N=S[O];if(N[N.length-1]==="%"&&(M[O]=!0),N=parseFloat(N),M[O]&&(N=N/100*255),N<0||N>255)return;k.push(Math.floor(N))}var $=M[1]||M[2]||M[3],H=M[1]&&M[2]&&M[3];if($&&!H)return;var q=S[4];if(q!==void 0){if(q=parseFloat(q),q<0||q>1)return;k.push(q)}}return k},zs=function(m){return Tr[m.toLowerCase()]},ao=function(m){return(ne(m)?m:null)||zs(m)||ji(m)||Ma(m)||xi(m)},Tr={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]},Fn=function(m){for(var k=m.map,S=m.keys,M=S.length,O=0;O=m||Ye<0||Z&&mt>=O}function Ee(){var st=wo();if(_e(st))return Be(st);$=setTimeout(Ee,Le(st))}function Be(st){return $=void 0,ce&&S?ve(st):(S=M=void 0,N)}function Re(){$!==void 0&&clearTimeout($),q=0,S=H=M=$=void 0}function Ve(){return $===void 0?N:Be(wo())}function ct(){var st=wo(),Ye=_e(st);if(S=arguments,M=this,H=st,Ye){if($===void 0)return me(H);if(Z)return clearTimeout($),$=setTimeout(Ee,m),ve(H)}return $===void 0&&($=setTimeout(Ee,m)),N}return ct.cancel=Re,ct.flush=Ve,ct}var Nu=Bi,Ot=F?F.performance:null,W3=Ot&&Ot.now?function(){return Ot.now()}:function(){return Date.now()},Kt=function(){if(F){if(F.requestAnimationFrame)return function(x){F.requestAnimationFrame(x)};if(F.mozRequestAnimationFrame)return function(x){F.mozRequestAnimationFrame(x)};if(F.webkitRequestAnimationFrame)return function(x){F.webkitRequestAnimationFrame(x)};if(F.msRequestAnimationFrame)return function(x){F.msRequestAnimationFrame(x)}}return function(x){x&&setTimeout(function(){x(W3())},1e3/60)}}(),z0=function(m){return Kt(m)},Bp=W3,Y3=9261,$9=65599,c5=5381,Eh=function(m){for(var k=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Y3,S=k,M;M=m.next(),!M.done;)S=S*$9+M.value|0;return S},zg=function(m){var k=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Y3;return k*$9+m|0},bm=function(m){var k=arguments.length>1&&arguments[1]!==void 0?arguments[1]:c5;return(k<<5)+k+m|0},z9=function(m,k){return m*2097152+k},mm=function(m){return m[0]*2097152+m[1]},u5=function(m,k){return[zg(m[0],k[0]),bm(m[1],k[1])]},y1=function(m,k){var S={value:0,done:!1},M=0,O=m.length,N={next:function(){return M=0&&!(m[M]===k&&(m.splice(M,1),S));M--);},cS=function(m){m.splice(0,m.length)},uj=function(m,k){for(var S=0;S"u"?"undefined":u(Set))!==VJ?Set:UJ,uS=function(m,k){var S=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(m===void 0||k===void 0||!Pe(m)){ch("An element must have a core reference and parameters set");return}var M=k.group;if(M==null&&(k.data&&k.data.source!=null&&k.data.target!=null?M="edges":M="nodes"),M!=="nodes"&&M!=="edges"){ch("An element must be of type `nodes` or `edges`; you specified `"+M+"`");return}this.length=1,this[0]=this;var O=this._private={cy:m,single:!0,data:k.data||{},position:k.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:M,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!k.selected,selectable:k.selectable===void 0?!0:!!k.selectable,locked:!!k.locked,grabbed:!1,grabbable:k.grabbable===void 0?!0:!!k.grabbable,pannable:k.pannable===void 0?M==="edges":!!k.pannable,active:!1,classes:new Q7,animation:{current:[],queue:[]},rscratch:{},scratch:k.scratch||{},edges:[],children:[],parent:k.parent&&k.parent.isNode()?k.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(O.position.x==null&&(O.position.x=0),O.position.y==null&&(O.position.y=0),k.renderedPosition){var N=k.renderedPosition,$=m.pan(),H=m.zoom();O.position={x:(N.x-$.x)/H,y:(N.y-$.y)/H}}var q=[];ne(k.classes)?q=k.classes:be(k.classes)&&(q=k.classes.split(/\s+/));for(var Y=0,Z=q.length;YBe?1:0},Y=function(Ee,Be,Re,Ve,ct){var st;if(Re==null&&(Re=0),ct==null&&(ct=S),Re<0)throw new Error("lo must be non-negative");for(Ve==null&&(Ve=Ee.length);ReLt;0<=Lt?Je++:Je--)mt.push(Je);return mt}).apply(this).reverse(),Ye=[],Ve=0,ct=st.length;VeMt;0<=Mt?++mt:--mt)ut.push(N(Ee,Re));return ut},Le=function(Ee,Be,Re,Ve){var ct,st,Ye;for(Ve==null&&(Ve=S),ct=Ee[Re];Re>Be;){if(Ye=Re-1>>1,st=Ee[Ye],Ve(ct,st)<0){Ee[Re]=st,Re=Ye;continue}break}return Ee[Re]=ct},_e=function(Ee,Be,Re){var Ve,ct,st,Ye,mt;for(Re==null&&(Re=S),ct=Ee.length,mt=Be,st=Ee[Be],Ve=2*Be+1;Ve0;){var st=Be.pop(),Ye=_e(st),mt=st.id();if(ce[mt]=Ye,Ye!==1/0)for(var Je=st.neighborhood().intersect(me),Lt=0;Lt0)for(Dn.unshift(Yt);Z[vr];){var Nn=Z[vr];Dn.unshift(Nn.edge),Dn.unshift(Nn.node),ir=Nn.node,vr=ir.id()}return $.spawn(Dn)}}}},YJ={kruskal:function(m){m=m||function(Re){return 1};for(var k=this.byGroup(),S=k.nodes,M=k.edges,O=S.length,N=new Array(O),$=S,H=function(Ve){for(var ct=0;ct0;){if(ct(),Ye++,Ve===Y){for(var mt=[],Je=O,Lt=Y,Mt=Ee[Lt];mt.unshift(Je),Mt!=null&&mt.unshift(Mt),Je=_e[Lt],Je!=null;)Lt=Je.id(),Mt=Ee[Lt];return{found:!0,distance:Z[Ve],path:this.spawn(mt),steps:Ye}}ve[Ve]=!0;for(var ut=Re._private.edges,Wt=0;WtMt&&(me[Lt]=Mt,Be[Lt]=Je,Re[Lt]=ct),!O){var ut=Je*Y+mt;!O&&me[ut]>Mt&&(me[ut]=Mt,Be[ut]=mt,Re[ut]=ct)}}}for(var Wt=0;Wt1&&arguments[1]!==void 0?arguments[1]:N,yo=Re(xs),$a=[],Da=yo;;){if(Da==null)return k.spawn();var Bo=Be(Da),tr=Bo.edge,G=Bo.pred;if($a.unshift(Da[0]),Da.same(Rs)&&$a.length>0)break;tr!=null&&$a.unshift(tr),Da=G}return H.spawn($a)},st=0;st=0;Y--){var Z=q[Y],ce=Z[1],ve=Z[2];(k[ce]===$&&k[ve]===H||k[ce]===H&&k[ve]===$)&&q.splice(Y,1)}for(var me=0;meM;){var O=Math.floor(Math.random()*k.length);k=rZ(O,m,k),S--}return k},iZ={kargerStein:function(){var m=this,k=this.byGroup(),S=k.nodes,M=k.edges;M.unmergeBy(function(Dn){return Dn.isLoop()});var O=S.length,N=M.length,$=Math.ceil(Math.pow(Math.log(O)/Math.LN2,2)),H=Math.floor(O/nZ);if(O<2){ch("At least 2 nodes are required for Karger-Stein algorithm");return}for(var q=[],Y=0;Y1&&arguments[1]!==void 0?arguments[1]:0,S=arguments.length>2&&arguments[2]!==void 0?arguments[2]:m.length,M=1/0,O=k;O1&&arguments[1]!==void 0?arguments[1]:0,S=arguments.length>2&&arguments[2]!==void 0?arguments[2]:m.length,M=-1/0,O=k;O1&&arguments[1]!==void 0?arguments[1]:0,S=arguments.length>2&&arguments[2]!==void 0?arguments[2]:m.length,M=0,O=0,N=k;N1&&arguments[1]!==void 0?arguments[1]:0,S=arguments.length>2&&arguments[2]!==void 0?arguments[2]:m.length,M=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,O=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,N=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0;M?m=m.slice(k,S):(S0&&m.splice(0,k));for(var $=0,H=m.length-1;H>=0;H--){var q=m[H];N?isFinite(q)||(m[H]=-1/0,$++):m.splice(H,1)}O&&m.sort(function(ce,ve){return ce-ve});var Y=m.length,Z=Math.floor(Y/2);return Y%2!==0?m[Z+1+$]:(m[Z-1+$]+m[Z+$])/2},lZ=function(m){return Math.PI*m/180},hS=function(m,k){return Math.atan2(k,m)-Math.PI/2},iI=Math.log2||function(x){return Math.log(x)/Math.log(2)},fj=function(m){return m>0?1:m<0?-1:0},h5=function(m,k){return Math.sqrt(f5(m,k))},f5=function(m,k){var S=k.x-m.x,M=k.y-m.y;return S*S+M*M},hZ=function(m){for(var k=m.length,S=0,M=0;M=m.x1&&m.y2>=m.y1)return{x1:m.x1,y1:m.y1,x2:m.x2,y2:m.y2,w:m.x2-m.x1,h:m.y2-m.y1};if(m.w!=null&&m.h!=null&&m.w>=0&&m.h>=0)return{x1:m.x1,y1:m.y1,x2:m.x1+m.w,y2:m.y1+m.h,w:m.w,h:m.h}}},dZ=function(m){return{x1:m.x1,x2:m.x2,w:m.w,y1:m.y1,y2:m.y2,h:m.h}},gZ=function(m){m.x1=1/0,m.y1=1/0,m.x2=-1/0,m.y2=-1/0,m.w=0,m.h=0},pZ=function(m,k,S){return{x1:m.x1+k,x2:m.x2+k,y1:m.y1+S,y2:m.y2+S,w:m.w,h:m.h}},dj=function(m,k){m.x1=Math.min(m.x1,k.x1),m.x2=Math.max(m.x2,k.x2),m.w=m.x2-m.x1,m.y1=Math.min(m.y1,k.y1),m.y2=Math.max(m.y2,k.y2),m.h=m.y2-m.y1},bZ=function(m,k,S){m.x1=Math.min(m.x1,k),m.x2=Math.max(m.x2,k),m.w=m.x2-m.x1,m.y1=Math.min(m.y1,S),m.y2=Math.max(m.y2,S),m.h=m.y2-m.y1},fS=function(m){var k=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return m.x1-=k,m.x2+=k,m.y1-=k,m.y2+=k,m.w=m.x2-m.x1,m.h=m.y2-m.y1,m},dS=function(m){var k=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[0],S,M,O,N;if(k.length===1)S=M=O=N=k[0];else if(k.length===2)S=O=k[0],N=M=k[1];else if(k.length===4){var $=y(k,4);S=$[0],M=$[1],O=$[2],N=$[3]}return m.x1-=N,m.x2+=M,m.y1-=S,m.y2+=O,m.w=m.x2-m.x1,m.h=m.y2-m.y1,m},gj=function(m,k){m.x1=k.x1,m.y1=k.y1,m.x2=k.x2,m.y2=k.y2,m.w=m.x2-m.x1,m.h=m.y2-m.y1},sI=function(m,k){return!(m.x1>k.x2||k.x1>m.x2||m.x2k.y2||k.y1>m.y2)},e8=function(m,k,S){return m.x1<=k&&k<=m.x2&&m.y1<=S&&S<=m.y2},mZ=function(m,k){return e8(m,k.x,k.y)},pj=function(m,k){return e8(m,k.x1,k.y1)&&e8(m,k.x2,k.y2)},bj=function(m,k,S,M,O,N,$){var H=W9(O,N),q=O/2,Y=N/2,Z;{var ce=S-q+H-$,ve=M-Y-$,me=S+q-H+$,Le=ve;if(Z=Z3(m,k,S,M,ce,ve,me,Le,!1),Z.length>0)return Z}{var _e=S+q+$,Ee=M-Y+H-$,Be=_e,Re=M+Y-H+$;if(Z=Z3(m,k,S,M,_e,Ee,Be,Re,!1),Z.length>0)return Z}{var Ve=S-q+H-$,ct=M+Y+$,st=S+q-H+$,Ye=ct;if(Z=Z3(m,k,S,M,Ve,ct,st,Ye,!1),Z.length>0)return Z}{var mt=S-q-$,Je=M-Y+H-$,Lt=mt,Mt=M+Y-H+$;if(Z=Z3(m,k,S,M,mt,Je,Lt,Mt,!1),Z.length>0)return Z}var ut;{var Wt=S-q+H,Tt=M-Y+H;if(ut=G9(m,k,S,M,Wt,Tt,H+$),ut.length>0&&ut[0]<=Wt&&ut[1]<=Tt)return[ut[0],ut[1]]}{var _n=S+q-H,hn=M-Y+H;if(ut=G9(m,k,S,M,_n,hn,H+$),ut.length>0&&ut[0]>=_n&&ut[1]<=hn)return[ut[0],ut[1]]}{var Yt=S+q-H,Dn=M+Y-H;if(ut=G9(m,k,S,M,Yt,Dn,H+$),ut.length>0&&ut[0]>=Yt&&ut[1]>=Dn)return[ut[0],ut[1]]}{var ir=S-q+H,vr=M+Y-H;if(ut=G9(m,k,S,M,ir,vr,H+$),ut.length>0&&ut[0]<=ir&&ut[1]>=vr)return[ut[0],ut[1]]}return[]},vZ=function(m,k,S,M,O,N,$){var H=$,q=Math.min(S,O),Y=Math.max(S,O),Z=Math.min(M,N),ce=Math.max(M,N);return q-H<=m&&m<=Y+H&&Z-H<=k&&k<=ce+H},wZ=function(m,k,S,M,O,N,$,H,q){var Y={x1:Math.min(S,$,O)-q,x2:Math.max(S,$,O)+q,y1:Math.min(M,H,N)-q,y2:Math.max(M,H,N)+q};return!(mY.x2||kY.y2)},yZ=function(m,k,S,M){S-=M;var O=k*k-4*m*S;if(O<0)return[];var N=Math.sqrt(O),$=2*m,H=(-k+N)/$,q=(-k-N)/$;return[H,q]},xZ=function(m,k,S,M,O){var N=1e-5;m===0&&(m=N),k/=m,S/=m,M/=m;var $,H,q,Y,Z,ce,ve,me;if(H=(3*S-k*k)/9,q=-(27*M)+k*(9*S-2*(k*k)),q/=54,$=H*H*H+q*q,O[1]=0,ve=k/3,$>0){Z=q+Math.sqrt($),Z=Z<0?-Math.pow(-Z,1/3):Math.pow(Z,1/3),ce=q-Math.sqrt($),ce=ce<0?-Math.pow(-ce,1/3):Math.pow(ce,1/3),O[0]=-ve+Z+ce,ve+=(Z+ce)/2,O[4]=O[2]=-ve,ve=Math.sqrt(3)*(-ce+Z)/2,O[3]=ve,O[5]=-ve;return}if(O[5]=O[3]=0,$===0){me=q<0?-Math.pow(-q,1/3):Math.pow(q,1/3),O[0]=-ve+2*me,O[4]=O[2]=-(me+ve);return}H=-H,Y=H*H*H,Y=Math.acos(q/Math.sqrt(Y)),me=2*Math.sqrt(H),O[0]=-ve+me*Math.cos(Y/3),O[2]=-ve+me*Math.cos((Y+2*Math.PI)/3),O[4]=-ve+me*Math.cos((Y+4*Math.PI)/3)},kZ=function(m,k,S,M,O,N,$,H){var q=1*S*S-4*S*O+2*S*$+4*O*O-4*O*$+$*$+M*M-4*M*N+2*M*H+4*N*N-4*N*H+H*H,Y=1*9*S*O-3*S*S-3*S*$-6*O*O+3*O*$+9*M*N-3*M*M-3*M*H-6*N*N+3*N*H,Z=1*3*S*S-6*S*O+S*$-S*m+2*O*O+2*O*m-$*m+3*M*M-6*M*N+M*H-M*k+2*N*N+2*N*k-H*k,ce=1*S*O-S*S+S*m-O*m+M*N-M*M+M*k-N*k,ve=[];xZ(q,Y,Z,ce,ve);for(var me=1e-7,Le=[],_e=0;_e<6;_e+=2)Math.abs(ve[_e+1])=0&&ve[_e]<=1&&Le.push(ve[_e]);Le.push(1),Le.push(0);for(var Ee=-1,Be,Re,Ve,ct=0;ct=0?Veq?(m-O)*(m-O)+(k-N)*(k-N):Y-ce},Yd=function(m,k,S){for(var M,O,N,$,H,q=0,Y=0;Y=m&&m>=N||M<=m&&m<=N)H=(m-M)/(N-M)*($-O)+O,H>k&&q++;else continue;return q%2!==0},Uv=function(m,k,S,M,O,N,$,H,q){var Y=new Array(S.length),Z;H[0]!=null?(Z=Math.atan(H[1]/H[0]),H[0]<0?Z=Z+Math.PI/2:Z=-Z-Math.PI/2):Z=H;for(var ce=Math.cos(-Z),ve=Math.sin(-Z),me=0;me0){var _e=pS(Y,-q);Le=gS(_e)}else Le=Y;return Yd(m,k,Le)},TZ=function(m,k,S,M,O,N,$){for(var H=new Array(S.length),q=N/2,Y=$/2,Z=cI(N,$),ce=Z*Z,ve=0;ve=0&&_e<=1&&Be.push(_e),Ee>=0&&Ee<=1&&Be.push(Ee),Be.length===0)return[];var Re=Be[0]*H[0]+m,Ve=Be[0]*H[1]+k;if(Be.length>1){if(Be[0]==Be[1])return[Re,Ve];var ct=Be[1]*H[0]+m,st=Be[1]*H[1]+k;return[Re,Ve,ct,st]}else return[Re,Ve]},aI=function(m,k,S){return k<=m&&m<=S||S<=m&&m<=k?m:m<=k&&k<=S||S<=k&&k<=m?k:S},Z3=function(m,k,S,M,O,N,$,H,q){var Y=m-O,Z=S-m,ce=$-O,ve=k-N,me=M-k,Le=H-N,_e=ce*ve-Le*Y,Ee=Z*ve-me*Y,Be=Le*Z-ce*me;if(Be!==0){var Re=_e/Be,Ve=Ee/Be,ct=.001,st=0-ct,Ye=1+ct;return st<=Re&&Re<=Ye&&st<=Ve&&Ve<=Ye?[m+Re*Z,k+Re*me]:q?[m+Re*Z,k+Re*me]:[]}else return _e===0||Ee===0?aI(m,S,$)===$?[$,H]:aI(m,S,O)===O?[O,N]:aI(O,$,S)===S?[S,M]:[]:[]},K9=function(m,k,S,M,O,N,$,H){var q=[],Y,Z=new Array(S.length),ce=!0;N==null&&(ce=!1);var ve;if(ce){for(var me=0;me0){var Le=pS(Z,-H);ve=gS(Le)}else ve=Z}else ve=S;for(var _e,Ee,Be,Re,Ve=0;Ve2){for(var hn=[q[0],q[1]],Yt=Math.pow(hn[0]-m,2)+Math.pow(hn[1]-k,2),Dn=1;DnY&&(Y=Ve)},get:function(Re){return q[Re]}},ce=0;ce<$.length;ce++){var ve=$[ce],me=ve.id();S?H[me]=ve.outgoers().nodes():H[me]=ve.openNeighborhood().nodes(),Z.set(me,0)}for(var Le=function(Re){for(var Ve=$[Re].id(),ct=[],st={},Ye={},mt={},Je=new V9(function(Cr,Or){return mt[Cr]-mt[Or]}),Lt=0;Lt<$.length;Lt++){var Mt=$[Lt].id();st[Mt]=[],Ye[Mt]=0,mt[Mt]=1/0}for(Ye[Ve]=1,mt[Ve]=0,Je.push(Ve);!Je.empty();){var ut=Je.pop();if(ct.push(ut),O)for(var Wt=0;Wt0?hn=_n.edgesTo(Tt)[0]:hn=Tt.edgesTo(_n)[0];var Yt=M(hn);Tt=Tt.id(),mt[Tt]>mt[ut]+Yt&&(mt[Tt]=mt[ut]+Yt,Je.nodes.indexOf(Tt)<0?Je.push(Tt):Je.updateItem(Tt),Ye[Tt]=0,st[Tt]=[]),mt[Tt]==mt[ut]+Yt&&(Ye[Tt]=Ye[Tt]+Ye[ut],st[Tt].push(ut))}else for(var Dn=0;Dn0;){for(var pr=ct.pop(),Er=0;Er0&&$.push(S[H]);$.length!==0&&O.push(M.collection($))}return O},jZ=function(m,k){for(var S=0;S5&&arguments[5]!==void 0?arguments[5]:qZ,$=M,H,q,Y=0;Y=2?Y9(m,k,S,0,Sj,HZ):Y9(m,k,S,0,Cj)},squaredEuclidean:function(m,k,S){return Y9(m,k,S,0,Sj)},manhattan:function(m,k,S){return Y9(m,k,S,0,Cj)},max:function(m,k,S){return Y9(m,k,S,-1/0,VZ)}};r8["squared-euclidean"]=r8.squaredEuclidean,r8.squaredeuclidean=r8.squaredEuclidean;function mS(x,m,k,S,M,O){var N;return ae(x)?N=x:N=r8[x]||r8.euclidean,m===0&&ae(x)?N(M,O):N(m,k,S,M,O)}var UZ=q0({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),hI=function(m){return UZ(m)},vS=function(m,k,S,M,O){var N=O!=="kMedoids",$=N?function(Z){return S[Z]}:function(Z){return M[Z](S)},H=function(ce){return M[ce](k)},q=S,Y=k;return mS(m,M.length,$,H,q,Y)},fI=function(m,k,S){for(var M=S.length,O=new Array(M),N=new Array(M),$=new Array(k),H=null,q=0;qS)return!1}return!0},WZ=function(m,k,S){for(var M=0;M$&&($=k[q][Y],H=Y);O[H].push(m[q])}for(var Z=0;Z=O.threshold||O.mode==="dendrogram"&&m.length===1)return!1;var me=k[N],Le=k[M[N]],_e;O.mode==="dendrogram"?_e={left:me,right:Le,key:me.key}:_e={value:me.value.concat(Le.value),key:me.key},m[me.index]=_e,m.splice(Le.index,1),k[me.key]=_e;for(var Ee=0;EeS[Le.key][Be.key]&&(H=S[Le.key][Be.key])):O.linkage==="max"?(H=S[me.key][Be.key],S[me.key][Be.key]0&&M.push(O);return M},Nj=function(m,k,S){for(var M=[],O=0;O$&&(N=q,$=k[O*m+q])}N>0&&M.push(N)}for(var Y=0;Yq&&(H=Y,q=Z)}S[O]=N[H]}return M=Nj(m,k,S),M},Pj=function(m){for(var k=this.cy(),S=this.nodes(),M=cee(m),O={},N=0;N=Mt?(ut=Mt,Mt=Tt,Wt=_n):Tt>ut&&(ut=Tt);for(var hn=0;hn<$;hn++)Z[Lt*$+hn]=(1-M.damping)*(q[Lt*$+hn]-Mt)+M.damping*Re[hn];Z[Lt*$+Wt]=(1-M.damping)*(q[Lt*$+Wt]-ut)+M.damping*Re[Wt]}for(var Yt=0;Yt<$;Yt++){for(var Dn=0,ir=0;ir<$;ir++)Re[ir]=ce[ir*$+Yt],Ve[ir]=Math.max(0,Z[ir*$+Yt]),Dn+=Ve[ir];Dn-=Ve[Yt],Ve[Yt]=Z[Yt*$+Yt],Dn+=Ve[Yt];for(var vr=0;vr<$;vr++)ce[vr*$+Yt]=(1-M.damping)*Math.min(0,Dn-Ve[vr])+M.damping*Re[vr];ce[Yt*$+Yt]=(1-M.damping)*(Dn-Ve[Yt])+M.damping*Re[Yt]}for(var Nn=0,pr=0;pr<$;pr++){var Er=ce[pr*$+pr]+Z[pr*$+pr]>0?1:0;Ye[Je%M.minIterations*$+pr]=Er,Nn+=Er}if(Nn>0&&(Je>=M.minIterations-1||Je==M.maxIterations-1)){for(var Mr=0,Cr=0;Cr<$;Cr++){ct[Cr]=0;for(var Or=0;Or1||st>1)&&($=!0),Z[Re]=[],Be.outgoers().forEach(function(mt){mt.isEdge()&&Z[Re].push(mt.id())})}else ce[Re]=[void 0,Be.target().id()]}):N.forEach(function(Be){var Re=Be.id();if(Be.isNode()){var Ve=Be.degree(!0);Ve%2&&(H?q?$=!0:q=Re:H=Re),Z[Re]=[],Be.connectedEdges().forEach(function(ct){return Z[Re].push(ct.id())})}else ce[Re]=[Be.source().id(),Be.target().id()]});var ve={found:!1,trail:void 0};if($)return ve;if(q&&H)if(O){if(Y&&q!=Y)return ve;Y=q}else{if(Y&&q!=Y&&H!=Y)return ve;Y||(Y=q)}else Y||(Y=N[0].id());var me=function(Re){for(var Ve=Re,ct=[Re],st,Ye,mt;Z[Ve].length;)st=Z[Ve].shift(),Ye=ce[st][0],mt=ce[st][1],Ve!=mt?(Z[mt]=Z[mt].filter(function(Je){return Je!=st}),Ve=mt):!O&&Ve!=Ye&&(Z[Ye]=Z[Ye].filter(function(Je){return Je!=st}),Ve=Ye),ct.unshift(st),ct.unshift(Ve);return ct},Le=[],_e=[];for(_e=me(Y);_e.length!=1;)Z[_e[0]].length==0?(Le.unshift(N.getElementById(_e.shift())),Le.unshift(N.getElementById(_e.shift()))):_e=me(_e.shift()).concat(_e);Le.unshift(N.getElementById(_e.shift()));for(var Ee in Z)if(Z[Ee].length)return ve;return ve.found=!0,ve.trail=this.spawn(Le,!0),ve}},yS=function(){var m=this,k={},S=0,M=0,O=[],N=[],$={},H=function(ce,ve){for(var me=N.length-1,Le=[],_e=m.spawn();N[me].x!=ce||N[me].y!=ve;)Le.push(N.pop().edge),me--;Le.push(N.pop().edge),Le.forEach(function(Ee){var Be=Ee.connectedNodes().intersection(m);_e.merge(Ee),Be.forEach(function(Re){var Ve=Re.id(),ct=Re.connectedEdges().intersection(m);_e.merge(Re),k[Ve].cutVertex?_e.merge(ct.filter(function(st){return st.isLoop()})):_e.merge(ct)})}),O.push(_e)},q=function Z(ce,ve,me){ce===me&&(M+=1),k[ve]={id:S,low:S++,cutVertex:!1};var Le=m.getElementById(ve).connectedEdges().intersection(m);if(Le.size()===0)O.push(m.spawn(m.getElementById(ve)));else{var _e,Ee,Be,Re;Le.forEach(function(Ve){_e=Ve.source().id(),Ee=Ve.target().id(),Be=_e===ve?Ee:_e,Be!==me&&(Re=Ve.id(),$[Re]||($[Re]=!0,N.push({x:ve,y:Be,edge:Ve})),Be in k?k[ve].low=Math.min(k[ve].low,k[Be].id):(Z(ce,Be,ve),k[ve].low=Math.min(k[ve].low,k[Be].low),k[ve].id<=k[Be].low&&(k[ve].cutVertex=!0,H(ve,Be))))})}};m.forEach(function(Z){if(Z.isNode()){var ce=Z.id();ce in k||(M=0,q(ce,ce),k[ce].cutVertex=M>1)}});var Y=Object.keys(k).filter(function(Z){return k[Z].cutVertex}).map(function(Z){return m.getElementById(Z)});return{cut:m.spawn(Y),components:O}},bee={hopcroftTarjanBiconnected:yS,htbc:yS,htb:yS,hopcroftTarjanBiconnectedComponents:yS},xS=function(){var m=this,k={},S=0,M=[],O=[],N=m.spawn(m),$=function H(q){O.push(q),k[q]={index:S,low:S++,explored:!1};var Y=m.getElementById(q).connectedEdges().intersection(m);if(Y.forEach(function(Le){var _e=Le.target().id();_e!==q&&(_e in k||H(_e),k[_e].explored||(k[q].low=Math.min(k[q].low,k[_e].low)))}),k[q].index===k[q].low){for(var Z=m.spawn();;){var ce=O.pop();if(Z.merge(m.getElementById(ce)),k[ce].low=k[q].index,k[ce].explored=!0,ce===q)break}var ve=Z.edgesWith(Z),me=Z.merge(ve);M.push(me),N=N.difference(me)}};return m.forEach(function(H){if(H.isNode()){var q=H.id();q in k||$(q)}}),{cut:N,components:M}},mee={tarjanStronglyConnected:xS,tsc:xS,tscc:xS,tarjanStronglyConnectedComponents:xS},Bj={};[H9,WJ,YJ,QJ,ZJ,tZ,iZ,LZ,t8,n8,lI,zZ,eee,aee,dee,pee,bee,mee].forEach(function(x){yt(Bj,x)});/*! +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) +*/var Fj=0,Rj=1,jj=2,Gv=function x(m){if(!(this instanceof x))return new x(m);this.id="Thenable/1.0.7",this.state=Fj,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},typeof m=="function"&&m.call(this,this.fulfill.bind(this),this.reject.bind(this))};Gv.prototype={fulfill:function(m){return $j(this,Rj,"fulfillValue",m)},reject:function(m){return $j(this,jj,"rejectReason",m)},then:function(m,k){var S=this,M=new Gv;return S.onFulfilled.push(Hj(m,M,"fulfill")),S.onRejected.push(Hj(k,M,"reject")),zj(S),M.proxy}};var $j=function(m,k,S,M){return m.state===Fj&&(m.state=k,m[S]=M,zj(m)),m},zj=function(m){m.state===Rj?qj(m,"onFulfilled",m.fulfillValue):m.state===jj&&qj(m,"onRejected",m.rejectReason)},qj=function(m,k,S){if(m[k].length!==0){var M=m[k];m[k]=[];var O=function(){for(var $=0;$0}},clearQueue:function(){return function(){var k=this,S=k.length!==void 0,M=S?k:[k],O=this._private.cy||this;if(!O.styleEnabled())return this;for(var N=0;N-1}var vte=mte;function wte(x,m){var k=this.__data__,S=TS(k,x);return S<0?(++this.size,k.push([x,m])):k[S][1]=m,this}var yte=wte;function a8(x){var m=-1,k=x==null?0:x.length;for(this.clear();++m-1&&x%1==0&&x0&&this.spawn(M).updateStyle().emit("class"),k},addClass:function(m){return this.toggleClass(m,!0)},hasClass:function(m){var k=this[0];return k!=null&&k._private.classes.has(m)},toggleClass:function(m,k){ne(m)||(m=m.match(/\S+/g)||[]);for(var S=this,M=k===void 0,O=[],N=0,$=S.length;N<$;N++)for(var H=S[N],q=H._private.classes,Y=!1,Z=0;Z0&&this.spawn(O).updateStyle().emit("class"),S},removeClass:function(m){return this.toggleClass(m,!1)},flashClass:function(m,k){var S=this;if(k==null)k=250;else if(k===0)return S;return S.addClass(m),setTimeout(function(){S.removeClass(m)},k),S}};SS.className=SS.classNames=SS.classes;var Rc={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:`"(?:\\\\"|[^"])*"|'(?:\\\\'|[^'])*'`,number:ln,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};Rc.variable="(?:[\\w-.]|(?:\\\\"+Rc.metaChar+"))+",Rc.className="(?:[\\w-]|(?:\\\\"+Rc.metaChar+"))+",Rc.value=Rc.string+"|"+Rc.number,Rc.id=Rc.variable,function(){var x,m,k;for(x=Rc.comparatorOp.split("|"),k=0;k=0)&&m!=="="&&(Rc.comparatorOp+="|\\!"+m)}();var Pu=function(){return{checks:[]}},hs={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},mI=[{selector:":selected",matches:function(m){return m.selected()}},{selector:":unselected",matches:function(m){return!m.selected()}},{selector:":selectable",matches:function(m){return m.selectable()}},{selector:":unselectable",matches:function(m){return!m.selectable()}},{selector:":locked",matches:function(m){return m.locked()}},{selector:":unlocked",matches:function(m){return!m.locked()}},{selector:":visible",matches:function(m){return m.visible()}},{selector:":hidden",matches:function(m){return!m.visible()}},{selector:":transparent",matches:function(m){return m.transparent()}},{selector:":grabbed",matches:function(m){return m.grabbed()}},{selector:":free",matches:function(m){return!m.grabbed()}},{selector:":removed",matches:function(m){return m.removed()}},{selector:":inside",matches:function(m){return!m.removed()}},{selector:":grabbable",matches:function(m){return m.grabbable()}},{selector:":ungrabbable",matches:function(m){return!m.grabbable()}},{selector:":animated",matches:function(m){return m.animated()}},{selector:":unanimated",matches:function(m){return!m.animated()}},{selector:":parent",matches:function(m){return m.isParent()}},{selector:":childless",matches:function(m){return m.isChildless()}},{selector:":child",matches:function(m){return m.isChild()}},{selector:":orphan",matches:function(m){return m.isOrphan()}},{selector:":nonorphan",matches:function(m){return m.isChild()}},{selector:":compound",matches:function(m){return m.isNode()?m.isParent():m.source().isParent()||m.target().isParent()}},{selector:":loop",matches:function(m){return m.isLoop()}},{selector:":simple",matches:function(m){return m.isSimple()}},{selector:":active",matches:function(m){return m.active()}},{selector:":inactive",matches:function(m){return!m.active()}},{selector:":backgrounding",matches:function(m){return m.backgrounding()}},{selector:":nonbackgrounding",matches:function(m){return!m.backgrounding()}}].sort(function(x,m){return zr(x.selector,m.selector)}),Ene=function(){for(var x={},m,k=0;k0&&Y.edgeCount>0)return hu("The selector `"+m+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(Y.edgeCount>1)return hu("The selector `"+m+"` is invalid because it uses multiple edge selectors"),!1;Y.edgeCount===1&&hu("The selector `"+m+"` 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},Ane=function(){if(this.toStringCache!=null)return this.toStringCache;for(var m=function(Y){return Y??""},k=function(Y){return be(Y)?'"'+Y+'"':m(Y)},S=function(Y){return" "+Y+" "},M=function(Y,Z){var ce=Y.type,ve=Y.value;switch(ce){case hs.GROUP:{var me=m(ve);return me.substring(0,me.length-1)}case hs.DATA_COMPARE:{var Le=Y.field,_e=Y.operator;return"["+Le+S(m(_e))+k(ve)+"]"}case hs.DATA_BOOL:{var Ee=Y.operator,Be=Y.field;return"["+m(Ee)+Be+"]"}case hs.DATA_EXIST:{var Re=Y.field;return"["+Re+"]"}case hs.META_COMPARE:{var Ve=Y.operator,ct=Y.field;return"[["+ct+S(m(Ve))+k(ve)+"]]"}case hs.STATE:return ve;case hs.ID:return"#"+ve;case hs.CLASS:return"."+ve;case hs.PARENT:case hs.CHILD:return O(Y.parent,Z)+S(">")+O(Y.child,Z);case hs.ANCESTOR:case hs.DESCENDANT:return O(Y.ancestor,Z)+" "+O(Y.descendant,Z);case hs.COMPOUND_SPLIT:{var st=O(Y.left,Z),Ye=O(Y.subject,Z),mt=O(Y.right,Z);return st+(st.length>0?" ":"")+Ye+mt}case hs.TRUE:return""}},O=function(Y,Z){return Y.checks.reduce(function(ce,ve,me){return ce+(Z===Y&&me===0?"$":"")+M(ve,Z)},"")},N="",$=0;$1&&$=0&&(k=k.replace("!",""),Z=!0),k.indexOf("@")>=0&&(k=k.replace("@",""),Y=!0),(O||$||Y)&&(H=!O&&!N?"":""+m,q=""+S),Y&&(m=H=H.toLowerCase(),S=q=q.toLowerCase()),k){case"*=":M=H.indexOf(q)>=0;break;case"$=":M=H.indexOf(q,H.length-q.length)>=0;break;case"^=":M=H.indexOf(q)===0;break;case"=":M=m===S;break;case">":ce=!0,M=m>S;break;case">=":ce=!0,M=m>=S;break;case"<":ce=!0,M=m0;){var Y=M.shift();m(Y),O.add(Y.id()),$&&S(M,O,Y)}return x}function l$(x,m,k){if(k.isParent())for(var S=k._private.children,M=0;M1&&arguments[1]!==void 0?arguments[1]:!0;return yI(this,x,m,l$)};function h$(x,m,k){if(k.isChild()){var S=k._private.parent;m.has(S.id())||x.push(S)}}u8.forEachUp=function(x){var m=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return yI(this,x,m,h$)};function Pne(x,m,k){h$(x,m,k),l$(x,m,k)}u8.forEachUpAndDown=function(x){var m=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return yI(this,x,m,Pne)},u8.ancestors=u8.parents;var x1,f$;x1=f$={data:fu.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:fu.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:fu.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:fu.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:fu.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:fu.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var m=this[0];if(m)return m._private.data.id}},x1.attr=x1.data,x1.removeAttr=x1.removeData;var ny=f$,J9={};function xI(x){return function(m){var k=this;if(m===void 0&&(m=!0),k.length!==0)if(k.isNode()&&!k.removed()){for(var S=0,M=k[0],O=M._private.edges,N=0;Nm}),minIndegree:l8("indegree",function(x,m){return xm}),minOutdegree:l8("outdegree",function(x,m){return xm})}),yt(J9,{totalDegree:function(m){for(var k=0,S=this.nodes(),M=0;M0,ce=Z;Z&&(Y=Y[0]);var ve=ce?Y.position():{x:0,y:0};k!==void 0?q.position(m,k+ve[m]):O!==void 0&&q.position({x:O.x+ve.x,y:O.y+ve.y})}else{var me=S.position(),Le=$?S.parent():null,_e=Le&&Le.length>0,Ee=_e;_e&&(Le=Le[0]);var Be=Ee?Le.position():{x:0,y:0};return O={x:me.x-Be.x,y:me.y-Be.y},m===void 0?O:O[m]}else if(!N)return;return this}},W2.modelPosition=W2.point=W2.position,W2.modelPositions=W2.points=W2.positions,W2.renderedPoint=W2.renderedPosition,W2.relativePoint=W2.relativePosition;var Bne=d$,h8,ry;h8=ry={},ry.renderedBoundingBox=function(x){var m=this.boundingBox(x),k=this.cy(),S=k.zoom(),M=k.pan(),O=m.x1*S+M.x,N=m.x2*S+M.x,$=m.y1*S+M.y,H=m.y2*S+M.y;return{x1:O,x2:N,y1:$,y2:H,w:N-O,h:H-$}},ry.dirtyCompoundBoundsCache=function(){var x=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,m=this.cy();return!m.styleEnabled()||!m.hasCompoundNodes()?this:(this.forEachUp(function(k){if(k.isParent()){var S=k._private;S.compoundBoundsClean=!1,S.bbCache=null,x||k.emitAndNotify("bounds")}}),this)},ry.updateCompoundBounds=function(){var x=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,m=this.cy();if(!m.styleEnabled()||!m.hasCompoundNodes())return this;if(!x&&m.batching())return this;function k(N){if(!N.isParent())return;var $=N._private,H=N.children(),q=N.pstyle("compound-sizing-wrt-labels").value==="include",Y={width:{val:N.pstyle("min-width").pfValue,left:N.pstyle("min-width-bias-left"),right:N.pstyle("min-width-bias-right")},height:{val:N.pstyle("min-height").pfValue,top:N.pstyle("min-height-bias-top"),bottom:N.pstyle("min-height-bias-bottom")}},Z=H.boundingBox({includeLabels:q,includeOverlays:!1,useCache:!1}),ce=$.position;(Z.w===0||Z.h===0)&&(Z={w:N.pstyle("width").pfValue,h:N.pstyle("height").pfValue},Z.x1=ce.x-Z.w/2,Z.x2=ce.x+Z.w/2,Z.y1=ce.y-Z.h/2,Z.y2=ce.y+Z.h/2);function ve(Je,Lt,Mt){var ut=0,Wt=0,Tt=Lt+Mt;return Je>0&&Tt>0&&(ut=Lt/Tt*Je,Wt=Mt/Tt*Je),{biasDiff:ut,biasComplementDiff:Wt}}function me(Je,Lt,Mt,ut){if(Mt.units==="%")switch(ut){case"width":return Je>0?Mt.pfValue*Je:0;case"height":return Lt>0?Mt.pfValue*Lt:0;case"average":return Je>0&&Lt>0?Mt.pfValue*(Je+Lt)/2:0;case"min":return Je>0&&Lt>0?Je>Lt?Mt.pfValue*Lt:Mt.pfValue*Je:0;case"max":return Je>0&&Lt>0?Je>Lt?Mt.pfValue*Je:Mt.pfValue*Lt:0;default:return 0}else return Mt.units==="px"?Mt.pfValue:0}var Le=Y.width.left.value;Y.width.left.units==="px"&&Y.width.val>0&&(Le=Le*100/Y.width.val);var _e=Y.width.right.value;Y.width.right.units==="px"&&Y.width.val>0&&(_e=_e*100/Y.width.val);var Ee=Y.height.top.value;Y.height.top.units==="px"&&Y.height.val>0&&(Ee=Ee*100/Y.height.val);var Be=Y.height.bottom.value;Y.height.bottom.units==="px"&&Y.height.val>0&&(Be=Be*100/Y.height.val);var Re=ve(Y.width.val-Z.w,Le,_e),Ve=Re.biasDiff,ct=Re.biasComplementDiff,st=ve(Y.height.val-Z.h,Ee,Be),Ye=st.biasDiff,mt=st.biasComplementDiff;$.autoPadding=me(Z.w,Z.h,N.pstyle("padding"),N.pstyle("padding-relative-to").value),$.autoWidth=Math.max(Z.w,Y.width.val),ce.x=(-Ve+Z.x1+Z.x2+ct)/2,$.autoHeight=Math.max(Z.h,Y.height.val),ce.y=(-Ye+Z.y1+Z.y2+mt)/2}for(var S=0;Sm.x2?M:m.x2,m.y1=Sm.y2?O:m.y2,m.w=m.x2-m.x1,m.h=m.y2-m.y1)},b5=function(m,k){return k==null?m:Y2(m,k.x1,k.y1,k.x2,k.y2)},Z9=function(m,k,S){return K2(m,k,S)},_S=function(m,k,S){if(!k.cy().headless()){var M=k._private,O=M.rstyle,N=O.arrowWidth/2,$=k.pstyle(S+"-arrow-shape").value,H,q;if($!=="none"){S==="source"?(H=O.srcX,q=O.srcY):S==="target"?(H=O.tgtX,q=O.tgtY):(H=O.midX,q=O.midY);var Y=M.arrowBounds=M.arrowBounds||{},Z=Y[S]=Y[S]||{};Z.x1=H-N,Z.y1=q-N,Z.x2=H+N,Z.y2=q+N,Z.w=Z.x2-Z.x1,Z.h=Z.y2-Z.y1,fS(Z,1),Y2(m,Z.x1,Z.y1,Z.x2,Z.y2)}}},kI=function(m,k,S){if(!k.cy().headless()){var M;S?M=S+"-":M="";var O=k._private,N=O.rstyle,$=k.pstyle(M+"label").strValue;if($){var H=k.pstyle("text-halign"),q=k.pstyle("text-valign"),Y=Z9(N,"labelWidth",S),Z=Z9(N,"labelHeight",S),ce=Z9(N,"labelX",S),ve=Z9(N,"labelY",S),me=k.pstyle(M+"text-margin-x").pfValue,Le=k.pstyle(M+"text-margin-y").pfValue,_e=k.isEdge(),Ee=k.pstyle(M+"text-rotation"),Be=k.pstyle("text-outline-width").pfValue,Re=k.pstyle("text-border-width").pfValue,Ve=Re/2,ct=k.pstyle("text-background-padding").pfValue,st=2,Ye=Z,mt=Y,Je=mt/2,Lt=Ye/2,Mt,ut,Wt,Tt;if(_e)Mt=ce-Je,ut=ce+Je,Wt=ve-Lt,Tt=ve+Lt;else{switch(H.value){case"left":Mt=ce-mt,ut=ce;break;case"center":Mt=ce-Je,ut=ce+Je;break;case"right":Mt=ce,ut=ce+mt;break}switch(q.value){case"top":Wt=ve-Ye,Tt=ve;break;case"center":Wt=ve-Lt,Tt=ve+Lt;break;case"bottom":Wt=ve,Tt=ve+Ye;break}}Mt+=me-Math.max(Be,Ve)-ct-st,ut+=me+Math.max(Be,Ve)+ct+st,Wt+=Le-Math.max(Be,Ve)-ct-st,Tt+=Le+Math.max(Be,Ve)+ct+st;var _n=S||"main",hn=O.labelBounds,Yt=hn[_n]=hn[_n]||{};Yt.x1=Mt,Yt.y1=Wt,Yt.x2=ut,Yt.y2=Tt,Yt.w=ut-Mt,Yt.h=Tt-Wt;var Dn=_e&&Ee.strValue==="autorotate",ir=Ee.pfValue!=null&&Ee.pfValue!==0;if(Dn||ir){var vr=Dn?Z9(O.rstyle,"labelAngle",S):Ee.pfValue,Nn=Math.cos(vr),pr=Math.sin(vr),Er=(Mt+ut)/2,Mr=(Wt+Tt)/2;if(!_e){switch(H.value){case"left":Er=ut;break;case"right":Er=Mt;break}switch(q.value){case"top":Mr=Tt;break;case"bottom":Mr=Wt;break}}var Cr=function(pa,Mi){return pa=pa-Er,Mi=Mi-Mr,{x:pa*Nn-Mi*pr+Er,y:pa*pr+Mi*Nn+Mr}},Or=Cr(Mt,Wt),Wn=Cr(Mt,Tt),br=Cr(ut,Wt),Sr=Cr(ut,Tt);Mt=Math.min(Or.x,Wn.x,br.x,Sr.x),ut=Math.max(Or.x,Wn.x,br.x,Sr.x),Wt=Math.min(Or.y,Wn.y,br.y,Sr.y),Tt=Math.max(Or.y,Wn.y,br.y,Sr.y)}var Nr=_n+"Rot",Si=hn[Nr]=hn[Nr]||{};Si.x1=Mt,Si.y1=Wt,Si.x2=ut,Si.y2=Tt,Si.w=ut-Mt,Si.h=Tt-Wt,Y2(m,Mt,Wt,ut,Tt),Y2(O.labelBounds.all,Mt,Wt,ut,Tt)}return m}},Fne=function(m,k){if(!k.cy().headless()){var S=k.pstyle("outline-opacity").value,M=k.pstyle("outline-width").value;if(S>0&&M>0){var O=k.pstyle("outline-offset").value,N=k.pstyle("shape").value,$=M+O,H=(m.w+$*2)/m.w,q=(m.h+$*2)/m.h,Y=0,Z=0;["diamond","pentagon","round-triangle"].includes(N)?(H=(m.w+$*2.4)/m.w,Z=-$/3.6):["concave-hexagon","rhomboid","right-rhomboid"].includes(N)?H=(m.w+$*2.4)/m.w:N==="star"?(H=(m.w+$*2.8)/m.w,q=(m.h+$*2.6)/m.h,Z=-$/3.8):N==="triangle"?(H=(m.w+$*2.8)/m.w,q=(m.h+$*2.4)/m.h,Z=-$/1.4):N==="vee"&&(H=(m.w+$*4.4)/m.w,q=(m.h+$*3.8)/m.h,Z=-$*.5);var ce=m.h*q-m.h,ve=m.w*H-m.w;if(dS(m,[Math.ceil(ce/2),Math.ceil(ve/2)]),Y!=0||Z!==0){var me=pZ(m,Y,Z);dj(m,me)}}}},Rne=function(m,k){var S=m._private.cy,M=S.styleEnabled(),O=S.headless(),N=Wd(),$=m._private,H=m.isNode(),q=m.isEdge(),Y,Z,ce,ve,me,Le,_e=$.rstyle,Ee=H&&M?m.pstyle("bounds-expansion").pfValue:[0],Be=function(fs){return fs.pstyle("display").value!=="none"},Re=!M||Be(m)&&(!q||Be(m.source())&&Be(m.target()));if(Re){var Ve=0,ct=0;M&&k.includeOverlays&&(Ve=m.pstyle("overlay-opacity").value,Ve!==0&&(ct=m.pstyle("overlay-padding").value));var st=0,Ye=0;M&&k.includeUnderlays&&(st=m.pstyle("underlay-opacity").value,st!==0&&(Ye=m.pstyle("underlay-padding").value));var mt=Math.max(ct,Ye),Je=0,Lt=0;if(M&&(Je=m.pstyle("width").pfValue,Lt=Je/2),H&&k.includeNodes){var Mt=m.position();me=Mt.x,Le=Mt.y;var ut=m.outerWidth(),Wt=ut/2,Tt=m.outerHeight(),_n=Tt/2;Y=me-Wt,Z=me+Wt,ce=Le-_n,ve=Le+_n,Y2(N,Y,ce,Z,ve),M&&k.includeOutlines&&Fne(N,m)}else if(q&&k.includeEdges)if(M&&!O){var hn=m.pstyle("curve-style").strValue;if(Y=Math.min(_e.srcX,_e.midX,_e.tgtX),Z=Math.max(_e.srcX,_e.midX,_e.tgtX),ce=Math.min(_e.srcY,_e.midY,_e.tgtY),ve=Math.max(_e.srcY,_e.midY,_e.tgtY),Y-=Lt,Z+=Lt,ce-=Lt,ve+=Lt,Y2(N,Y,ce,Z,ve),hn==="haystack"){var Yt=_e.haystackPts;if(Yt&&Yt.length===2){if(Y=Yt[0].x,ce=Yt[0].y,Z=Yt[1].x,ve=Yt[1].y,Y>Z){var Dn=Y;Y=Z,Z=Dn}if(ce>ve){var ir=ce;ce=ve,ve=ir}Y2(N,Y-Lt,ce-Lt,Z+Lt,ve+Lt)}}else if(hn==="bezier"||hn==="unbundled-bezier"||hn==="segments"||hn==="taxi"){var vr;switch(hn){case"bezier":case"unbundled-bezier":vr=_e.bezierPts;break;case"segments":case"taxi":vr=_e.linePts;break}if(vr!=null)for(var Nn=0;NnZ){var Wn=Y;Y=Z,Z=Wn}if(ce>ve){var br=ce;ce=ve,ve=br}Y-=Lt,Z+=Lt,ce-=Lt,ve+=Lt,Y2(N,Y,ce,Z,ve)}if(M&&k.includeEdges&&q&&(_S(N,m,"mid-source"),_S(N,m,"mid-target"),_S(N,m,"source"),_S(N,m,"target")),M){var Sr=m.pstyle("ghost").value==="yes";if(Sr){var Nr=m.pstyle("ghost-offset-x").pfValue,Si=m.pstyle("ghost-offset-y").pfValue;Y2(N,N.x1+Nr,N.y1+Si,N.x2+Nr,N.y2+Si)}}var ys=$.bodyBounds=$.bodyBounds||{};gj(ys,N),dS(ys,Ee),fS(ys,1),M&&(Y=N.x1,Z=N.x2,ce=N.y1,ve=N.y2,Y2(N,Y-mt,ce-mt,Z+mt,ve+mt));var pa=$.overlayBounds=$.overlayBounds||{};gj(pa,N),dS(pa,Ee),fS(pa,1);var Mi=$.labelBounds=$.labelBounds||{};Mi.all!=null?gZ(Mi.all):Mi.all=Wd(),M&&k.includeLabels&&(k.includeMainLabels&&kI(N,m,null),q&&(k.includeSourceLabels&&kI(N,m,"source"),k.includeTargetLabels&&kI(N,m,"target")))}return N.x1=jp(N.x1),N.y1=jp(N.y1),N.x2=jp(N.x2),N.y2=jp(N.y2),N.w=jp(N.x2-N.x1),N.h=jp(N.y2-N.y1),N.w>0&&N.h>0&&Re&&(dS(N,Ee),fS(N,1)),N},b$=function(m){var k=0,S=function(N){return(N?1:0)<0&&arguments[0]!==void 0?arguments[0]:Xne,m=arguments.length>1?arguments[1]:void 0,k=0;k=0;$--)N($);return this},X2.removeAllListeners=function(){return this.removeListener("*")},X2.emit=X2.trigger=function(x,m,k){var S=this.listeners,M=S.length;return this.emitting++,ne(m)||(m=[m]),MS(this,function(O,N){k!=null&&(S=[{event:N.event,type:N.type,namespace:N.namespace,callback:k}],M=S.length);for(var $=function(Y){var Z=S[Y];if(Z.type===N.type&&(!Z.namespace||Z.namespace===N.namespace||Z.namespace===Yne)&&O.eventMatches(O.context,Z,N)){var ce=[N];m!=null&&uj(ce,m),O.beforeEmit(O.context,Z,N),Z.conf&&Z.conf.one&&(O.listeners=O.listeners.filter(function(Le){return Le!==Z}));var ve=O.callbackContext(O.context,Z,N),me=Z.callback.apply(ve,ce);O.afterEmit(O.context,Z,N),me===!1&&(N.stopPropagation(),N.preventDefault())}},H=0;H1&&!N){var $=this.length-1,H=this[$],q=H._private.data.id;this[$]=void 0,this[m]=H,O.set(q,{ele:H,index:m})}return this.length--,this},unmergeOne:function(m){m=m[0];var k=this._private,S=m._private.data.id,M=k.map,O=M.get(S);if(!O)return this;var N=O.index;return this.unmergeAt(N),this},unmerge:function(m){var k=this._private.cy;if(!m)return this;if(m&&be(m)){var S=m;m=k.mutableElements().filter(S)}for(var M=0;M=0;k--){var S=this[k];m(S)&&this.unmergeAt(k)}return this},map:function(m,k){for(var S=[],M=this,O=0;OS&&(S=H,M=$)}return{value:S,ele:M}},min:function(m,k){for(var S=1/0,M,O=this,N=0;N=0&&O"u"?"undefined":u(Symbol))!=m&&u(Symbol.iterator)!=m;k&&(DS[Symbol.iterator]=function(){var S=this,M={value:void 0,done:!1},O=0,N=this.length;return b({next:function(){return O1&&arguments[1]!==void 0?arguments[1]:!0,S=this[0],M=S.cy();if(M.styleEnabled()&&S){this.cleanStyle();var O=S._private.style[m];return O??(k?M.style().getDefaultProperty(m):null)}},numericStyle:function(m){var k=this[0];if(k.cy().styleEnabled()&&k){var S=k.pstyle(m);return S.pfValue!==void 0?S.pfValue:S.value}},numericStyleUnits:function(m){var k=this[0];if(k.cy().styleEnabled()&&k)return k.pstyle(m).units},renderedStyle:function(m){var k=this.cy();if(!k.styleEnabled())return this;var S=this[0];if(S)return k.style().getRenderedStyle(S,m)},style:function(m,k){var S=this.cy();if(!S.styleEnabled())return this;var M=!1,O=S.style();if(se(m)){var N=m;O.applyBypass(this,N,M),this.emitAndNotify("style")}else if(be(m))if(k===void 0){var $=this[0];return $?O.getStylePropertyValue($,m):void 0}else O.applyBypass(this,m,k,M),this.emitAndNotify("style");else if(m===void 0){var H=this[0];return H?O.getRawStyle(H):void 0}return this},removeStyle:function(m){var k=this.cy();if(!k.styleEnabled())return this;var S=!1,M=k.style(),O=this;if(m===void 0)for(var N=0;N0&&m.push(Y[0]),m.push($[0])}return this.spawn(m,!0).filter(x)},"neighborhood"),closedNeighborhood:function(m){return this.neighborhood().add(this).filter(m)},openNeighborhood:function(m){return this.neighborhood(m)}}),k1.neighbourhood=k1.neighborhood,k1.closedNeighbourhood=k1.closedNeighborhood,k1.openNeighbourhood=k1.openNeighborhood,yt(k1,{source:Rp(function(m){var k=this[0],S;return k&&(S=k._private.source||k.cy().collection()),S&&m?S.filter(m):S},"source"),target:Rp(function(m){var k=this[0],S;return k&&(S=k._private.target||k.cy().collection()),S&&m?S.filter(m):S},"target"),sources:D$({attr:"source"}),targets:D$({attr:"target"})});function D$(x){return function(k){for(var S=[],M=0;M0);return N},component:function(){var m=this[0];return m.cy().mutableElements().components(m)[0]}}),k1.componentsOf=k1.components;var V0=function(m,k){var S=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1,M=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(m===void 0){ch("A collection must have a reference to the core");return}var O=new wm,N=!1;if(!k)k=[];else if(k.length>0&&se(k[0])&&!U(k[0])){N=!0;for(var $=[],H=new Q7,q=0,Y=k.length;q0&&arguments[0]!==void 0?arguments[0]:!0,m=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,k=this,S=k.cy(),M=S._private,O=[],N=[],$,H=0,q=k.length;H0){for(var ir=$.length===k.length?k:new V0(S,$),vr=0;vr0&&arguments[0]!==void 0?arguments[0]:!0,m=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,k=this,S=[],M={},O=k._private.cy;function N(Tt){for(var _n=Tt._private.edges,hn=0;hn<_n.length;hn++)H(_n[hn])}function $(Tt){for(var _n=Tt._private.children,hn=0;hn<_n.length;hn++)H(_n[hn])}function H(Tt){var _n=M[Tt.id()];m&&Tt.removed()||_n||(M[Tt.id()]=!0,Tt.isNode()?(S.push(Tt),N(Tt),$(Tt)):S.unshift(Tt))}for(var q=0,Y=k.length;q0&&(x?Mt.emitAndNotify("remove"):m&&Mt.emit("remove"));for(var ut=0;ut0?ut=Tt:Mt=Tt;while(Math.abs(Wt)>N&&++_n<$);return Tt}function ct(Lt){for(var Mt=0,ut=1,Wt=H-1;ut!==Wt&&ce[ut]<=Lt;++ut)Mt+=q;--ut;var Tt=(Lt-ce[ut])/(ce[ut+1]-ce[ut]),_n=Mt+Tt*q,hn=Ee(_n,x,k);return hn>=O?Be(Lt,_n):hn===0?_n:Ve(Lt,Mt,Mt+q)}var st=!1;function Ye(){st=!0,(x!==m||k!==S)&&Re()}var mt=function(Mt){return st||Ye(),x===m&&k===S?Mt:Mt===0?0:Mt===1?1:_e(ct(Mt),m,S)};mt.getControlPoints=function(){return[{x,y:m},{x:k,y:S}]};var Je="generateBezier("+[x,m,k,S]+")";return mt.toString=function(){return Je},mt}/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */var ore=function(){function x(S){return-S.tension*S.x-S.friction*S.v}function m(S,M,O){var N={x:S.x+O.dx*M,v:S.v+O.dv*M,tension:S.tension,friction:S.friction};return{dx:N.v,dv:x(N)}}function k(S,M){var O={dx:S.v,dv:x(S)},N=m(S,M*.5,O),$=m(S,M*.5,N),H=m(S,M,$),q=1/6*(O.dx+2*(N.dx+$.dx)+H.dx),Y=1/6*(O.dv+2*(N.dv+$.dv)+H.dv);return S.x=S.x+q*M,S.v=S.v+Y*M,S}return function S(M,O,N){var $={x:-1,v:0,tension:null,friction:null},H=[0],q=0,Y=1/1e4,Z=16/1e3,ce,ve,me;for(M=parseFloat(M)||500,O=parseFloat(O)||20,N=N||null,$.tension=M,$.friction=O,ce=N!==null,ce?(q=S(M,O),ve=q/N*Z):ve=Z;me=k(me||$,ve),H.push(1+me.x),q+=16,Math.abs(me.x)>Y&&Math.abs(me.v)>Y;);return ce?function(Le){return H[Le*(H.length-1)|0]}:q}}(),rl=function(m,k,S,M){var O=are(m,k,S,M);return function(N,$,H){return N+($-N)*O(H)}},BS={linear:function(m,k,S){return m+(k-m)*S},ease:rl(.25,.1,.25,1),"ease-in":rl(.42,0,1,1),"ease-out":rl(0,0,.58,1),"ease-in-out":rl(.42,0,.58,1),"ease-in-sine":rl(.47,0,.745,.715),"ease-out-sine":rl(.39,.575,.565,1),"ease-in-out-sine":rl(.445,.05,.55,.95),"ease-in-quad":rl(.55,.085,.68,.53),"ease-out-quad":rl(.25,.46,.45,.94),"ease-in-out-quad":rl(.455,.03,.515,.955),"ease-in-cubic":rl(.55,.055,.675,.19),"ease-out-cubic":rl(.215,.61,.355,1),"ease-in-out-cubic":rl(.645,.045,.355,1),"ease-in-quart":rl(.895,.03,.685,.22),"ease-out-quart":rl(.165,.84,.44,1),"ease-in-out-quart":rl(.77,0,.175,1),"ease-in-quint":rl(.755,.05,.855,.06),"ease-out-quint":rl(.23,1,.32,1),"ease-in-out-quint":rl(.86,0,.07,1),"ease-in-expo":rl(.95,.05,.795,.035),"ease-out-expo":rl(.19,1,.22,1),"ease-in-out-expo":rl(1,0,0,1),"ease-in-circ":rl(.6,.04,.98,.335),"ease-out-circ":rl(.075,.82,.165,1),"ease-in-out-circ":rl(.785,.135,.15,.86),spring:function(m,k,S){if(S===0)return BS.linear;var M=ore(m,k,S);return function(O,N,$){return O+(N-O)*M($)}},"cubic-bezier":rl};function N$(x,m,k,S,M){if(S===1||m===k)return k;var O=M(m,k,S);return x==null||((x.roundValue||x.color)&&(O=Math.round(O)),x.min!==void 0&&(O=Math.max(O,x.min)),x.max!==void 0&&(O=Math.min(O,x.max))),O}function P$(x,m){return x.pfValue!=null||x.value!=null?x.pfValue!=null&&(m==null||m.type.units!=="%")?x.pfValue:x.value:x}function g8(x,m,k,S,M){var O=M!=null?M.type:null;k<0?k=0:k>1&&(k=1);var N=P$(x,M),$=P$(m,M);if(X(N)&&X($))return N$(O,N,$,k,S);if(ne(N)&&ne($)){for(var H=[],q=0;q<$.length;q++){var Y=N[q],Z=$[q];if(Y!=null&&Z!=null){var ce=N$(O,Y,Z,k,S);H.push(ce)}else H.push(Z)}return H}}function cre(x,m,k,S){var M=!S,O=x._private,N=m._private,$=N.easing,H=N.startTime,q=S?x:x.cy(),Y=q.style();if(!N.easingImpl)if($==null)N.easingImpl=BS.linear;else{var Z;if(be($)){var ce=Y.parse("transition-timing-function",$);Z=ce.value}else Z=$;var ve,me;be(Z)?(ve=Z,me=[]):(ve=Z[1],me=Z.slice(2).map(function(ir){return+ir})),me.length>0?(ve==="spring"&&me.push(N.duration),N.easingImpl=BS[ve].apply(null,me)):N.easingImpl=BS[ve]}var Le=N.easingImpl,_e;if(N.duration===0?_e=1:_e=(k-H)/N.duration,N.applying&&(_e=N.progress),_e<0?_e=0:_e>1&&(_e=1),N.delay==null){var Ee=N.startPosition,Be=N.position;if(Be&&M&&!x.locked()){var Re={};ak(Ee.x,Be.x)&&(Re.x=g8(Ee.x,Be.x,_e,Le)),ak(Ee.y,Be.y)&&(Re.y=g8(Ee.y,Be.y,_e,Le)),x.position(Re)}var Ve=N.startPan,ct=N.pan,st=O.pan,Ye=ct!=null&&S;Ye&&(ak(Ve.x,ct.x)&&(st.x=g8(Ve.x,ct.x,_e,Le)),ak(Ve.y,ct.y)&&(st.y=g8(Ve.y,ct.y,_e,Le)),x.emit("pan"));var mt=N.startZoom,Je=N.zoom,Lt=Je!=null&&S;Lt&&(ak(mt,Je)&&(O.zoom=U9(O.minZoom,g8(mt,Je,_e,Le),O.maxZoom)),x.emit("zoom")),(Ye||Lt)&&x.emit("viewport");var Mt=N.style;if(Mt&&Mt.length>0&&M){for(var ut=0;ut=0;Ye--){var mt=st[Ye];mt()}st.splice(0,st.length)},Be=ve.length-1;Be>=0;Be--){var Re=ve[Be],Ve=Re._private;if(Ve.stopped){ve.splice(Be,1),Ve.hooked=!1,Ve.playing=!1,Ve.started=!1,Ee(Ve.frames);continue}!Ve.playing&&!Ve.applying||(Ve.playing&&Ve.applying&&(Ve.applying=!1),Ve.started||ure(Y,Re,x),cre(Y,Re,x,Z),Ve.applying&&(Ve.applying=!1),Ee(Ve.frames),Ve.step!=null&&Ve.step(x),Re.completed()&&(ve.splice(Be,1),Ve.hooked=!1,Ve.playing=!1,Ve.started=!1,Ee(Ve.completes)),Le=!0)}return!Z&&ve.length===0&&me.length===0&&S.push(Y),Le}for(var O=!1,N=0;N0?m.notify("draw",k):m.notify("draw")),k.unmerge(S),m.emit("step")}var lre={animate:fu.animate(),animation:fu.animation(),animated:fu.animated(),clearQueue:fu.clearQueue(),delay:fu.delay(),delayAnimation:fu.delayAnimation(),stop:fu.stop(),addToAnimationPool:function(m){var k=this;k.styleEnabled()&&k._private.aniEles.merge(m)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var m=this;if(m._private.animationsRunning=!0,!m.styleEnabled())return;function k(){m._private.animationsRunning&&z0(function(O){B$(O,m),k()})}var S=m.renderer();S&&S.beforeRender?S.beforeRender(function(O,N){B$(N,m)},S.beforeRenderPriorities.animations):k()}},hre={qualifierCompare:function(m,k){return m==null||k==null?m==null&&k==null:m.sameText(k)},eventMatches:function(m,k,S){var M=k.qualifier;return M!=null?m!==S.target&&U(S.target)&&M.matches(S.target):!0},addEventFields:function(m,k){k.cy=m,k.target=m},callbackContext:function(m,k,S){return k.qualifier!=null?S.target:m}},FS=function(m){return be(m)?new ey(m):m},F$={createEmitter:function(){var m=this._private;return m.emitter||(m.emitter=new LS(hre,this)),this},emitter:function(){return this._private.emitter},on:function(m,k,S){return this.emitter().on(m,FS(k),S),this},removeListener:function(m,k,S){return this.emitter().removeListener(m,FS(k),S),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(m,k,S){return this.emitter().one(m,FS(k),S),this},once:function(m,k,S){return this.emitter().one(m,FS(k),S),this},emit:function(m,k){return this.emitter().emit(m,k),this},emitAndNotify:function(m,k){return this.emit(m),this.notify(m,k),this}};fu.eventAliasesOn(F$);var MI={png:function(m){var k=this._private.renderer;return m=m||{},k.png(m)},jpg:function(m){var k=this._private.renderer;return m=m||{},m.bg=m.bg||"#fff",k.jpg(m)}};MI.jpeg=MI.jpg;var RS={layout:function(m){var k=this;if(m==null){ch("Layout options must be specified to make a layout");return}if(m.name==null){ch("A `name` must be specified to make a layout");return}var S=m.name,M=k.extension("layout",S);if(M==null){ch("No such layout `"+S+"` found. Did you forget to import it and `cytoscape.use()` it?");return}var O;be(m.eles)?O=k.$(m.eles):O=m.eles!=null?m.eles:k.$();var N=new M(yt({},m,{cy:k,eles:O}));return N}};RS.createLayout=RS.makeLayout=RS.layout;var fre={notify:function(m,k){var S=this._private;if(this.batching()){S.batchNotifications=S.batchNotifications||{};var M=S.batchNotifications[m]=S.batchNotifications[m]||this.collection();k!=null&&M.merge(k);return}if(S.notificationsEnabled){var O=this.renderer();this.destroyed()||!O||O.notify(m,k)}},notifications:function(m){var k=this._private;return m===void 0?k.notificationsEnabled:(k.notificationsEnabled=!!m,this)},noNotifications:function(m){this.notifications(!1),m(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var m=this._private;return m.batchCount==null&&(m.batchCount=0),m.batchCount===0&&(m.batchStyleEles=this.collection(),m.batchNotifications={}),m.batchCount++,this},endBatch:function(){var m=this._private;if(m.batchCount===0)return this;if(m.batchCount--,m.batchCount===0){m.batchStyleEles.updateStyle();var k=this.renderer();Object.keys(m.batchNotifications).forEach(function(S){var M=m.batchNotifications[S];M.empty()?k.notify(S):k.notify(S,M)})}return this},batch:function(m){return this.startBatch(),m(),this.endBatch(),this},batchData:function(m){var k=this;return this.batch(function(){for(var S=Object.keys(m),M=0;M0;)k.removeChild(k.childNodes[0]);m._private.renderer=null,m.mutableElements().forEach(function(S){var M=S._private;M.rscratch={},M.rstyle={},M.animation.current=[],M.animation.queue=[]})},onRender:function(m){return this.on("render",m)},offRender:function(m){return this.off("render",m)}};DI.invalidateDimensions=DI.resize;var jS={collection:function(m,k){return be(m)?this.$(m):xe(m)?m.collection():ne(m)?(k||(k={}),new V0(this,m,k.unique,k.removed)):new V0(this)},nodes:function(m){var k=this.$(function(S){return S.isNode()});return m?k.filter(m):k},edges:function(m){var k=this.$(function(S){return S.isEdge()});return m?k.filter(m):k},$:function(m){var k=this._private.elements;return m?k.filter(m):k.spawnSelf()},mutableElements:function(){return this._private.elements}};jS.elements=jS.filter=jS.$;var E1={},ok="t",gre="f";E1.apply=function(x){for(var m=this,k=m._private,S=k.cy,M=S.collection(),O=0;O0;if(ce||Z&&ve){var me=void 0;ce&&ve||ce?me=q.properties:ve&&(me=q.mappedProperties);for(var Le=0;Le1&&(Ve=1),$.color){var st=S.valueMin[0],Ye=S.valueMax[0],mt=S.valueMin[1],Je=S.valueMax[1],Lt=S.valueMin[2],Mt=S.valueMax[2],ut=S.valueMin[3]==null?1:S.valueMin[3],Wt=S.valueMax[3]==null?1:S.valueMax[3],Tt=[Math.round(st+(Ye-st)*Ve),Math.round(mt+(Je-mt)*Ve),Math.round(Lt+(Mt-Lt)*Ve),Math.round(ut+(Wt-ut)*Ve)];O={bypass:S.bypass,name:S.name,value:Tt,strValue:"rgb("+Tt[0]+", "+Tt[1]+", "+Tt[2]+")"}}else if($.number){var _n=S.valueMin+(S.valueMax-S.valueMin)*Ve;O=this.parse(S.name,_n,S.bypass,ce)}else return!1;if(!O)return Le(),!1;O.mapping=S,S=O;break}case N.data:{for(var hn=S.field.split("."),Yt=Z.data,Dn=0;Dn0&&O>0){for(var $={},H=!1,q=0;q0?x.delayAnimation(N).play().promise().then(Re):Re()}).then(function(){return x.animation({style:$,duration:O,easing:x.pstyle("transition-timing-function").value,queue:!1}).play().promise()}).then(function(){k.removeBypasses(x,M),x.emitAndNotify("style"),S.transitioning=!1})}else S.transitioning&&(this.removeBypasses(x,M),x.emitAndNotify("style"),S.transitioning=!1)},E1.checkTrigger=function(x,m,k,S,M,O){var N=this.properties[m],$=M(N);$!=null&&$(k,S)&&O(N)},E1.checkZOrderTrigger=function(x,m,k,S){var M=this;this.checkTrigger(x,m,k,S,function(O){return O.triggersZOrder},function(){M._private.cy.notify("zorder",x)})},E1.checkBoundsTrigger=function(x,m,k,S){this.checkTrigger(x,m,k,S,function(M){return M.triggersBounds},function(M){x.dirtyCompoundBoundsCache(),x.dirtyBoundingBoxCache(),M.triggersBoundsOfParallelBeziers&&m==="curve-style"&&(k==="bezier"||S==="bezier")&&x.parallelEdges().forEach(function(O){O.isBundledBezier()&&O.dirtyBoundingBoxCache()}),M.triggersBoundsOfConnectedEdges&&m==="display"&&(k==="none"||S==="none")&&x.connectedEdges().forEach(function(O){O.dirtyBoundingBoxCache()})})},E1.checkTriggers=function(x,m,k,S){x.dirtyStyleCache(),this.checkZOrderTrigger(x,m,k,S),this.checkBoundsTrigger(x,m,k,S)};var ck={};ck.applyBypass=function(x,m,k,S){var M=this,O=[],N=!0;if(m==="*"||m==="**"){if(k!==void 0)for(var $=0;$M.length?S=S.substr(M.length):S=""}function H(){O.length>N.length?O=O.substr(N.length):O=""}for(;;){var q=S.match(/^\s*$/);if(q)break;var Y=S.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!Y){hu("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+S);break}M=Y[0];var Z=Y[1];if(Z!=="core"){var ce=new ey(Z);if(ce.invalid){hu("Skipping parsing of block: Invalid selector found in string stylesheet: "+Z),$();continue}}var ve=Y[2],me=!1;O=ve;for(var Le=[];;){var _e=O.match(/^\s*$/);if(_e)break;var Ee=O.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!Ee){hu("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+ve),me=!0;break}N=Ee[0];var Be=Ee[1],Re=Ee[2],Ve=m.properties[Be];if(!Ve){hu("Skipping property: Invalid property name in: "+N),H();continue}var ct=k.parse(Be,Re);if(!ct){hu("Skipping property: Invalid property definition in: "+N),H();continue}Le.push({name:Be,val:Re}),H()}if(me){$();break}k.selector(Z);for(var st=0;st=7&&m[0]==="d"&&(Y=new RegExp($.data.regex).exec(m))){if(k)return!1;var ce=$.data;return{name:x,value:Y,strValue:""+m,mapped:ce,field:Y[1],bypass:k}}else if(m.length>=10&&m[0]==="m"&&(Z=new RegExp($.mapData.regex).exec(m))){if(k||q.multiple)return!1;var ve=$.mapData;if(!(q.color||q.number))return!1;var me=this.parse(x,Z[4]);if(!me||me.mapped)return!1;var Le=this.parse(x,Z[5]);if(!Le||Le.mapped)return!1;if(me.pfValue===Le.pfValue||me.strValue===Le.strValue)return hu("`"+x+": "+m+"` is not a valid mapper because the output range is zero; converting to `"+x+": "+me.strValue+"`"),this.parse(x,me.strValue);if(q.color){var _e=me.value,Ee=Le.value,Be=_e[0]===Ee[0]&&_e[1]===Ee[1]&&_e[2]===Ee[2]&&(_e[3]===Ee[3]||(_e[3]==null||_e[3]===1)&&(Ee[3]==null||Ee[3]===1));if(Be)return!1}return{name:x,value:Z,strValue:""+m,mapped:ve,field:Z[1],fieldMin:parseFloat(Z[2]),fieldMax:parseFloat(Z[3]),valueMin:me.value,valueMax:Le.value,bypass:k}}}if(q.multiple&&S!=="multiple"){var Re;if(H?Re=m.split(/\s+/):ne(m)?Re=m:Re=[m],q.evenMultiple&&Re.length%2!==0)return null;for(var Ve=[],ct=[],st=[],Ye="",mt=!1,Je=0;Je0?" ":"")+Lt.strValue}return q.validate&&!q.validate(Ve,ct)?null:q.singleEnum&&mt?Ve.length===1&&be(Ve[0])?{name:x,value:Ve[0],strValue:Ve[0],bypass:k}:null:{name:x,value:Ve,pfValue:st,strValue:Ye,bypass:k,units:ct}}var Mt=function(){for(var Sr=0;Srq.max||q.strictMax&&m===q.max))return null;var hn={name:x,value:m,strValue:""+m+(ut||""),units:ut,bypass:k};return q.unitless||ut!=="px"&&ut!=="em"?hn.pfValue=m:hn.pfValue=ut==="px"||!ut?m:this.getEmSizeInPixels()*m,(ut==="ms"||ut==="s")&&(hn.pfValue=ut==="ms"?m:1e3*m),(ut==="deg"||ut==="rad")&&(hn.pfValue=ut==="rad"?m:lZ(m)),ut==="%"&&(hn.pfValue=m/100),hn}else if(q.propList){var Yt=[],Dn=""+m;if(Dn!=="none"){for(var ir=Dn.split(/\s*,\s*|\s+/),vr=0;vr0&&$>0&&!isNaN(S.w)&&!isNaN(S.h)&&S.w>0&&S.h>0){H=Math.min((N-2*k)/S.w,($-2*k)/S.h),H=H>this._private.maxZoom?this._private.maxZoom:H,H=H=S.minZoom&&(S.maxZoom=k),this},minZoom:function(m){return m===void 0?this._private.minZoom:this.zoomRange({min:m})},maxZoom:function(m){return m===void 0?this._private.maxZoom:this.zoomRange({max:m})},getZoomedViewport:function(m){var k=this._private,S=k.pan,M=k.zoom,O,N,$=!1;if(k.zoomingEnabled||($=!0),X(m)?N=m:se(m)&&(N=m.level,m.position!=null?O=lS(m.position,M,S):m.renderedPosition!=null&&(O=m.renderedPosition),O!=null&&!k.panningEnabled&&($=!0)),N=N>k.maxZoom?k.maxZoom:N,N=Nk.maxZoom||!k.zoomingEnabled?N=!0:(k.zoom=H,O.push("zoom"))}if(M&&(!N||!m.cancelOnFailedZoom)&&k.panningEnabled){var q=m.pan;X(q.x)&&(k.pan.x=q.x,$=!1),X(q.y)&&(k.pan.y=q.y,$=!1),$||O.push("pan")}return O.length>0&&(O.push("viewport"),this.emit(O.join(" ")),this.notify("viewport")),this},center:function(m){var k=this.getCenterPan(m);return k&&(this._private.pan=k,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(m,k){if(this._private.panningEnabled){if(be(m)){var S=m;m=this.mutableElements().filter(S)}else xe(m)||(m=this.mutableElements());if(m.length!==0){var M=m.boundingBox(),O=this.width(),N=this.height();k=k===void 0?this._private.zoom:k;var $={x:(O-k*(M.x1+M.x2))/2,y:(N-k*(M.y1+M.y2))/2};return $}}},reset:function(){return!this._private.panningEnabled||!this._private.zoomingEnabled?this:(this.viewport({pan:{x:0,y:0},zoom:1}),this)},invalidateSize:function(){this._private.sizeCache=null},size:function(){var m=this._private,k=m.container,S=this;return m.sizeCache=m.sizeCache||(k?function(){var M=S.window().getComputedStyle(k),O=function($){return parseFloat(M.getPropertyValue($))};return{width:k.clientWidth-O("padding-left")-O("padding-right"),height:k.clientHeight-O("padding-top")-O("padding-bottom")}}():{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var m=this._private.pan,k=this._private.zoom,S=this.renderedExtent(),M={x1:(S.x1-m.x)/k,x2:(S.x2-m.x)/k,y1:(S.y1-m.y)/k,y2:(S.y2-m.y)/k};return M.w=M.x2-M.x1,M.h=M.y2-M.y1,M},renderedExtent:function(){var m=this.width(),k=this.height();return{x1:0,y1:0,x2:m,y2:k,w:m,h:k}},multiClickDebounceTime:function(m){if(m)this._private.multiClickDebounceTime=m;else return this._private.multiClickDebounceTime;return this}};v5.centre=v5.center,v5.autolockNodes=v5.autolock,v5.autoungrabifyNodes=v5.autoungrabify;var uk={data:fu.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:fu.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:fu.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:fu.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};uk.attr=uk.data,uk.removeAttr=uk.removeData;var lk=function(m){var k=this;m=yt({},m);var S=m.container;S&&!W(S)&&W(S[0])&&(S=S[0]);var M=S?S._cyreg:null;M=M||{},M&&M.cy&&(M.cy.destroy(),M={});var O=M.readies=M.readies||[];S&&(S._cyreg=M),M.cy=k;var N=F!==void 0&&S!==void 0&&!m.headless,$=m;$.layout=yt({name:N?"grid":"null"},$.layout),$.renderer=yt({name:N?"canvas":"null"},$.renderer);var H=function(me,Le,_e){return Le!==void 0?Le:_e!==void 0?_e:me},q=this._private={container:S,ready:!1,options:$,elements:new V0(this),listeners:[],aniEles:new V0(this),data:$.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:H(!0,$.zoomingEnabled),userZoomingEnabled:H(!0,$.userZoomingEnabled),panningEnabled:H(!0,$.panningEnabled),userPanningEnabled:H(!0,$.userPanningEnabled),boxSelectionEnabled:H(!0,$.boxSelectionEnabled),autolock:H(!1,$.autolock,$.autolockNodes),autoungrabify:H(!1,$.autoungrabify,$.autoungrabifyNodes),autounselectify:H(!1,$.autounselectify),styleEnabled:$.styleEnabled===void 0?N:$.styleEnabled,zoom:X($.zoom)?$.zoom:1,pan:{x:se($.pan)&&X($.pan.x)?$.pan.x:0,y:se($.pan)&&X($.pan.y)?$.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:H(250,$.multiClickDebounceTime)};this.createEmitter(),this.selectionType($.selectionType),this.zoomRange({min:$.minZoom,max:$.maxZoom});var Y=function(me,Le){var _e=me.some(Ke);if(_e)return i8.all(me).then(Le);Le(me)};q.styleEnabled&&k.setStyle([]);var Z=yt({},$,$.renderer);k.initRenderer(Z);var ce=function(me,Le,_e){k.notifications(!1);var Ee=k.mutableElements();Ee.length>0&&Ee.remove(),me!=null&&(se(me)||ne(me))&&k.add(me),k.one("layoutready",function(Re){k.notifications(!0),k.emit(Re),k.one("load",Le),k.emitAndNotify("load")}).one("layoutstop",function(){k.one("done",_e),k.emit("done")});var Be=yt({},k._private.options.layout);Be.eles=k.elements(),k.layout(Be).run()};Y([$.style,$.elements],function(ve){var me=ve[0],Le=ve[1];q.styleEnabled&&k.style().append(me),ce(Le,function(){k.startAnimationLoop(),q.ready=!0,ae($.ready)&&k.on("ready",$.ready);for(var _e=0;_e0,H=Wd(m.boundingBox?m.boundingBox:{x1:0,y1:0,w:k.width(),h:k.height()}),q;if(xe(m.roots))q=m.roots;else if(ne(m.roots)){for(var Y=[],Z=0;Z0;){var _n=Tt(),hn=Lt(_n,ut);if(hn)_n.outgoers().filter(function(Mi){return Mi.isNode()&&S.has(Mi)}).forEach(Wt);else if(hn===null){hu("Detected double maximal shift for node `"+_n.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}Je();var Yt=0;if(m.avoidOverlap)for(var Dn=0;Dn0&&Ee[0].length<=3?Da/2:0),G=2*Math.PI/Ee[Fs].length*xs;return Fs===0&&Ee[0].length===1&&(tr=1),{x:Si.x+tr*Math.cos(G),y:Si.y+tr*Math.sin(G)}}else{var Bo={x:Si.x+(xs+1-(Rs+1)/2)*yo,y:(Fs+1)*$a};return Bo}};return S.nodes().layoutPositions(this,m,pa),this};var wre={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:function(m,k){return!0},ready:void 0,stop:void 0,transform:function(m,k){return k}};function $$(x){this.options=yt({},wre,x)}$$.prototype.run=function(){var x=this.options,m=x,k=x.cy,S=m.eles,M=m.counterclockwise!==void 0?!m.counterclockwise:m.clockwise,O=S.nodes().not(":parent");m.sort&&(O=O.sort(m.sort));for(var N=Wd(m.boundingBox?m.boundingBox:{x1:0,y1:0,w:k.width(),h:k.height()}),$={x:N.x1+N.w/2,y:N.y1+N.h/2},H=m.sweep===void 0?2*Math.PI-2*Math.PI/O.length:m.sweep,q=H/Math.max(1,O.length-1),Y,Z=0,ce=0;ce1&&m.avoidOverlap){Z*=1.75;var Ee=Math.cos(q)-Math.cos(0),Be=Math.sin(q)-Math.sin(0),Re=Math.sqrt(Z*Z/(Ee*Ee+Be*Be));Y=Math.max(Re,Y)}var Ve=function(st,Ye){var mt=m.startAngle+Ye*q*(M?1:-1),Je=Y*Math.cos(mt),Lt=Y*Math.sin(mt),Mt={x:$.x+Je,y:$.y+Lt};return Mt};return S.nodes().layoutPositions(this,m,Ve),this};var yre={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:function(m){return m.degree()},levelWidth:function(m){return m.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(m,k){return!0},ready:void 0,stop:void 0,transform:function(m,k){return k}};function z$(x){this.options=yt({},yre,x)}z$.prototype.run=function(){for(var x=this.options,m=x,k=m.counterclockwise!==void 0?!m.counterclockwise:m.clockwise,S=x.cy,M=m.eles,O=M.nodes().not(":parent"),N=Wd(m.boundingBox?m.boundingBox:{x1:0,y1:0,w:S.width(),h:S.height()}),$={x:N.x1+N.w/2,y:N.y1+N.h/2},H=[],q=0,Y=0;Y0){var ct=Math.abs(Be[0].value-Ve.value);ct>=_e&&(Be=[],Ee.push(Be))}Be.push(Ve)}var st=q+m.minNodeSpacing;if(!m.avoidOverlap){var Ye=Ee.length>0&&Ee[0].length>1,mt=Math.min(N.w,N.h)/2-st,Je=mt/(Ee.length+Ye?1:0);st=Math.min(st,Je)}for(var Lt=0,Mt=0;Mt1&&m.avoidOverlap){var _n=Math.cos(Tt)-Math.cos(0),hn=Math.sin(Tt)-Math.sin(0),Yt=Math.sqrt(st*st/(_n*_n+hn*hn));Lt=Math.max(Yt,Lt)}ut.r=Lt,Lt+=st}if(m.equidistant){for(var Dn=0,ir=0,vr=0;vr=x.numIter||(Are(S,x),S.temperature=S.temperature*x.coolingFactor,S.temperature=x.animationThreshold&&O(),z0(Z)}};Y()}else{for(;q;)q=N(H),H++;V$(S,x),$()}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};var kre=function(m,k,S){for(var M=S.eles.edges(),O=S.eles.nodes(),N=Wd(S.boundingBox?S.boundingBox:{x1:0,y1:0,w:m.width(),h:m.height()}),$={isCompound:m.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:O.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:M.size(),temperature:S.initialTemp,clientWidth:N.w,clientHeight:N.h,boundingBox:N},H=S.eles.components(),q={},Y=0;Y0){$.graphSet.push(mt);for(var Y=0;YM.count?0:M.graph},Tre=function x(m,k,S,M){var O=M.graphSet[S];if(-10)var Z=M.nodeOverlap*Y,ce=Math.sqrt($*$+H*H),ve=Z*$/ce,me=Z*H/ce;else var Le=VS(m,$,H),_e=VS(k,-1*$,-1*H),Ee=_e.x-Le.x,Be=_e.y-Le.y,Re=Ee*Ee+Be*Be,ce=Math.sqrt(Re),Z=(m.nodeRepulsion+k.nodeRepulsion)/Re,ve=Z*Ee/ce,me=Z*Be/ce;m.isLocked||(m.offsetX-=ve,m.offsetY-=me),k.isLocked||(k.offsetX+=ve,k.offsetY+=me)}},Dre=function(m,k,S,M){if(S>0)var O=m.maxX-k.minX;else var O=k.maxX-m.minX;if(M>0)var N=m.maxY-k.minY;else var N=k.maxY-m.minY;return O>=0&&N>=0?Math.sqrt(O*O+N*N):0},VS=function(m,k,S){var M=m.positionX,O=m.positionY,N=m.height||1,$=m.width||1,H=S/k,q=N/$,Y={};return k===0&&0S?(Y.x=M,Y.y=O+N/2,Y):0k&&-1*q<=H&&H<=q?(Y.x=M-$/2,Y.y=O-$*S/2/k,Y):0=q)?(Y.x=M+N*k/2/S,Y.y=O+N/2,Y):(0>S&&(H<=-1*q||H>=q)&&(Y.x=M-N*k/2/S,Y.y=O-N/2),Y)},Ire=function(m,k){for(var S=0;SS){var _e=k.gravity*ve/Le,Ee=k.gravity*me/Le;ce.offsetX+=_e,ce.offsetY+=Ee}}}}},Nre=function(m,k){var S=[],M=0,O=-1;for(S.push.apply(S,m.graphSet[0]),O+=m.graphSet[0].length;M<=O;){var N=S[M++],$=m.idToIndex[N],H=m.layoutNodes[$],q=H.children;if(0S)var O={x:S*m/M,y:S*k/M};else var O={x:m,y:k};return O},Fre=function x(m,k){var S=m.parentId;if(S!=null){var M=k.layoutNodes[k.idToIndex[S]],O=!1;if((M.maxX==null||m.maxX+M.padRight>M.maxX)&&(M.maxX=m.maxX+M.padRight,O=!0),(M.minX==null||m.minX-M.padLeftM.maxY)&&(M.maxY=m.maxY+M.padBottom,O=!0),(M.minY==null||m.minY-M.padTopEe&&(me+=_e+k.componentSpacing,ve=0,Le=0,_e=0)}}},Rre={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:function(m){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(m,k){return!0},ready:void 0,stop:void 0,transform:function(m,k){return k}};function U$(x){this.options=yt({},Rre,x)}U$.prototype.run=function(){var x=this.options,m=x,k=x.cy,S=m.eles,M=S.nodes().not(":parent");m.sort&&(M=M.sort(m.sort));var O=Wd(m.boundingBox?m.boundingBox:{x1:0,y1:0,w:k.width(),h:k.height()});if(O.h===0||O.w===0)S.nodes().layoutPositions(this,m,function(Er){return{x:O.x1,y:O.y1}});else{var N=M.size(),$=Math.sqrt(N*O.h/O.w),H=Math.round($),q=Math.round(O.w/O.h*$),Y=function(Mr){if(Mr==null)return Math.min(H,q);var Cr=Math.min(H,q);Cr==H?H=Mr:q=Mr},Z=function(Mr){if(Mr==null)return Math.max(H,q);var Cr=Math.max(H,q);Cr==H?H=Mr:q=Mr},ce=m.rows,ve=m.cols!=null?m.cols:m.columns;if(ce!=null&&ve!=null)H=ce,q=ve;else if(ce!=null&&ve==null)H=ce,q=Math.ceil(N/H);else if(ce==null&&ve!=null)q=ve,H=Math.ceil(N/q);else if(q*H>N){var me=Y(),Le=Z();(me-1)*Le>=N?Y(me-1):(Le-1)*me>=N&&Z(Le-1)}else for(;q*H=N?Z(Ee+1):Y(_e+1)}var Be=O.w/q,Re=O.h/H;if(m.condense&&(Be=0,Re=0),m.avoidOverlap)for(var Ve=0;Ve=q&&(_n=0,Tt++)},Yt={},Dn=0;Dn(_n=EZ(x,m,hn[Yt],hn[Yt+1],hn[Yt+2],hn[Yt+3])))return _e(Ye,_n),!0}else if(Je.edgeType==="bezier"||Je.edgeType==="multibezier"||Je.edgeType==="self"||Je.edgeType==="compound"){for(var hn=Je.allpts,Yt=0;Yt+5(_n=kZ(x,m,hn[Yt],hn[Yt+1],hn[Yt+2],hn[Yt+3],hn[Yt+4],hn[Yt+5])))return _e(Ye,_n),!0}for(var Dn=Dn||mt.source,ir=ir||mt.target,vr=M.getArrowWidth(Lt,Mt),Nn=[{name:"source",x:Je.arrowStartX,y:Je.arrowStartY,angle:Je.srcArrowAngle},{name:"target",x:Je.arrowEndX,y:Je.arrowEndY,angle:Je.tgtArrowAngle},{name:"mid-source",x:Je.midX,y:Je.midY,angle:Je.midsrcArrowAngle},{name:"mid-target",x:Je.midX,y:Je.midY,angle:Je.midtgtArrowAngle}],Yt=0;Yt0&&(Ee(Dn),Ee(ir))}function Re(Ye,mt,Je){return K2(Ye,mt,Je)}function Ve(Ye,mt){var Je=Ye._private,Lt=ce,Mt;mt?Mt=mt+"-":Mt="",Ye.boundingBox();var ut=Je.labelBounds[mt||"main"],Wt=Ye.pstyle(Mt+"label").value,Tt=Ye.pstyle("text-events").strValue==="yes";if(!(!Tt||!Wt)){var _n=Re(Je.rscratch,"labelX",mt),hn=Re(Je.rscratch,"labelY",mt),Yt=Re(Je.rscratch,"labelAngle",mt),Dn=Ye.pstyle(Mt+"text-margin-x").pfValue,ir=Ye.pstyle(Mt+"text-margin-y").pfValue,vr=ut.x1-Lt-Dn,Nn=ut.x2+Lt-Dn,pr=ut.y1-Lt-ir,Er=ut.y2+Lt-ir;if(Yt){var Mr=Math.cos(Yt),Cr=Math.sin(Yt),Or=function(pa,Mi){return pa=pa-_n,Mi=Mi-hn,{x:pa*Mr-Mi*Cr+_n,y:pa*Cr+Mi*Mr+hn}},Wn=Or(vr,pr),br=Or(vr,Er),Sr=Or(Nn,pr),Nr=Or(Nn,Er),Si=[Wn.x+Dn,Wn.y+ir,Sr.x+Dn,Sr.y+ir,Nr.x+Dn,Nr.y+ir,br.x+Dn,br.y+ir];if(Yd(x,m,Si))return _e(Ye),!0}else if(e8(ut,x,m))return _e(Ye),!0}}for(var ct=N.length-1;ct>=0;ct--){var st=N[ct];st.isNode()?Ee(st)||Ve(st):Be(st)||Ve(st)||Ve(st,"source")||Ve(st,"target")}return $},w5.getAllInBox=function(x,m,k,S){var M=this.getCachedZSortedEles().interactive,O=[],N=Math.min(x,k),$=Math.max(x,k),H=Math.min(m,S),q=Math.max(m,S);x=N,k=$,m=H,S=q;for(var Y=Wd({x1:x,y1:m,x2:k,y2:S}),Z=0;Z0?Math.max(wr-Es,0):Math.min(wr+Es,0)},Wt=ut(Lt,mt),Tt=ut(Mt,Je),_n=!1;Be===q?Ee=Math.abs(Wt)>Math.abs(Tt)?M:S:Be===H||Be===$?(Ee=S,_n=!0):(Be===O||Be===N)&&(Ee=M,_n=!0);var hn=Ee===S,Yt=hn?Tt:Wt,Dn=hn?Mt:Lt,ir=fj(Dn),vr=!1;!(_n&&(Ve||st))&&(Be===$&&Dn<0||Be===H&&Dn>0||Be===O&&Dn>0||Be===N&&Dn<0)&&(ir*=-1,Yt=ir*Math.abs(Yt),vr=!0);var Nn;if(Ve){var pr=ct<0?1+ct:ct;Nn=pr*Yt}else{var Er=ct<0?Yt:0;Nn=Er+ct*ir}var Mr=function(wr){return Math.abs(wr)=Math.abs(Yt)},Cr=Mr(Nn),Or=Mr(Math.abs(Yt)-Math.abs(Nn)),Wn=Cr||Or;if(Wn&&!vr)if(hn){var br=Math.abs(Dn)<=ce/2,Sr=Math.abs(Lt)<=ve/2;if(br){var Nr=(Y.x1+Y.x2)/2,Si=Y.y1,ys=Y.y2;k.segpts=[Nr,Si,Nr,ys]}else if(Sr){var pa=(Y.y1+Y.y2)/2,Mi=Y.x1,gi=Y.x2;k.segpts=[Mi,pa,gi,pa]}else k.segpts=[Y.x1,Y.y2]}else{var fs=Math.abs(Dn)<=Z/2,Fs=Math.abs(Mt)<=me/2;if(fs){var xs=(Y.y1+Y.y2)/2,Rs=Y.x1,yo=Y.x2;k.segpts=[Rs,xs,yo,xs]}else if(Fs){var $a=(Y.x1+Y.x2)/2,Da=Y.y1,Bo=Y.y2;k.segpts=[$a,Da,$a,Bo]}else k.segpts=[Y.x2,Y.y1]}else if(hn){var tr=Y.y1+Nn+(_e?ce/2*ir:0),G=Y.x1,Jn=Y.x2;k.segpts=[G,tr,Jn,tr]}else{var kr=Y.x1+Nn+(_e?Z/2*ir:0),lr=Y.y1,Vt=Y.y2;k.segpts=[kr,lr,kr,Vt]}},S1.tryToCorrectInvalidPoints=function(x,m){var k=x._private.rscratch;if(k.edgeType==="bezier"){var S=m.srcPos,M=m.tgtPos,O=m.srcW,N=m.srcH,$=m.tgtW,H=m.tgtH,q=m.srcShape,Y=m.tgtShape,Z=!X(k.startX)||!X(k.startY),ce=!X(k.arrowStartX)||!X(k.arrowStartY),ve=!X(k.endX)||!X(k.endY),me=!X(k.arrowEndX)||!X(k.arrowEndY),Le=3,_e=this.getArrowWidth(x.pstyle("width").pfValue,x.pstyle("arrow-scale").value)*this.arrowShapeWidth,Ee=Le*_e,Be=h5({x:k.ctrlpts[0],y:k.ctrlpts[1]},{x:k.startX,y:k.startY}),Re=BeTt.poolIndex()){var _n=Wt;Wt=Tt,Tt=_n}var hn=Je.srcPos=Wt.position(),Yt=Je.tgtPos=Tt.position(),Dn=Je.srcW=Wt.outerWidth(),ir=Je.srcH=Wt.outerHeight(),vr=Je.tgtW=Tt.outerWidth(),Nn=Je.tgtH=Tt.outerHeight(),pr=Je.srcShape=k.nodeShapes[m.getNodeShape(Wt)],Er=Je.tgtShape=k.nodeShapes[m.getNodeShape(Tt)];Je.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var Mr=0;Mr0){var br=O,Sr=f5(br,J7(k)),Nr=f5(br,J7(Wn)),Si=Sr;if(Nr2){var ys=f5(br,{x:Wn[2],y:Wn[3]});ys0){var G=N,Jn=f5(G,J7(k)),kr=f5(G,J7(tr)),lr=Jn;if(kr2){var Vt=f5(G,{x:tr[2],y:tr[3]});Vt=me||Ye){_e={cp:Ve,segment:st};break}}if(_e)break}var mt=_e.cp,Je=_e.segment,Lt=(me-Ee)/Je.length,Mt=Je.t1-Je.t0,ut=ve?Je.t0+Mt*Lt:Je.t1-Mt*Lt;ut=U9(0,ut,1),m=Z7(mt.p0,mt.p1,mt.p2,ut),ce=Hre(mt.p0,mt.p1,mt.p2,ut);break}case"straight":case"segments":case"haystack":{for(var Wt=0,Tt,_n,hn,Yt,Dn=S.allpts.length,ir=0;ir+3=me));ir+=2);var vr=me-_n,Nn=vr/Tt;Nn=U9(0,Nn,1),m=fZ(hn,Yt,Nn),ce=GS(hn,Yt);break}}N("labelX",Z,m.x),N("labelY",Z,m.y),N("labelAutoAngle",Z,ce)}};q("source"),q("target"),this.applyLabelDimensions(x)}},km.applyLabelDimensions=function(x){this.applyPrefixedLabelDimensions(x),x.isEdge()&&(this.applyPrefixedLabelDimensions(x,"source"),this.applyPrefixedLabelDimensions(x,"target"))},km.applyPrefixedLabelDimensions=function(x,m){var k=x._private,S=this.getLabelText(x,m),M=this.calculateLabelDimensions(x,S),O=x.pstyle("line-height").pfValue,N=x.pstyle("text-wrap").strValue,$=K2(k.rscratch,"labelWrapCachedLines",m)||[],H=N!=="wrap"?1:Math.max($.length,1),q=M.height/H,Y=q*O,Z=M.width,ce=M.height+(H-1)*(O-1)*q;J3(k.rstyle,"labelWidth",m,Z),J3(k.rscratch,"labelWidth",m,Z),J3(k.rstyle,"labelHeight",m,ce),J3(k.rscratch,"labelHeight",m,ce),J3(k.rscratch,"labelLineHeight",m,Y)},km.getLabelText=function(x,m){var k=x._private,S=m?m+"-":"",M=x.pstyle(S+"label").strValue,O=x.pstyle("text-transform").value,N=function(vr,Nn){return Nn?(J3(k.rscratch,vr,m,Nn),Nn):K2(k.rscratch,vr,m)};if(!M)return"";O=="none"||(O=="uppercase"?M=M.toUpperCase():O=="lowercase"&&(M=M.toLowerCase()));var $=x.pstyle("text-wrap").value;if($==="wrap"){var H=N("labelKey");if(H!=null&&N("labelWrapKey")===H)return N("labelWrapCachedText");for(var q="​",Y=M.split(` +`),Z=x.pstyle("text-max-width").pfValue,ce=x.pstyle("text-overflow-wrap").value,ve=ce==="anywhere",me=[],Le=/[\s\u200b]+/,_e=ve?"":" ",Ee=0;EeZ){for(var st=Be.split(Le),Ye="",mt=0;mtWt)break;Tt+=M[Yt],Yt===M.length-1&&(hn=!0)}return hn||(Tt+=_n),Tt}return M},km.getLabelJustification=function(x){var m=x.pstyle("text-justification").strValue,k=x.pstyle("text-halign").strValue;if(m==="auto")if(x.isNode())switch(k){case"left":return"right";case"right":return"left";default:return"center"}else return"center";else return m},km.calculateLabelDimensions=function(x,m){var k=this,S=ud(m,x._private.labelDimsKey),M=k.labelDimCache||(k.labelDimCache=[]),O=M[S];if(O!=null)return O;var N=0,$=x.pstyle("font-style").strValue,H=x.pstyle("font-size").pfValue,q=x.pstyle("font-family").strValue,Y=x.pstyle("font-weight").strValue,Z=this.labelCalcCanvas,ce=this.labelCalcCanvasContext;if(!Z){Z=this.labelCalcCanvas=document.createElement("canvas"),ce=this.labelCalcCanvasContext=Z.getContext("2d");var ve=Z.style;ve.position="absolute",ve.left="-9999px",ve.top="-9999px",ve.zIndex="-1",ve.visibility="hidden",ve.pointerEvents="none"}ce.font="".concat($," ").concat(Y," ").concat(H,"px ").concat(q);for(var me=0,Le=0,_e=m.split(` +`),Ee=0;Ee<_e.length;Ee++){var Be=_e[Ee],Re=ce.measureText(Be),Ve=Math.ceil(Re.width),ct=H;me=Math.max(Ve,me),Le+=ct}return me+=N,Le+=N,M[S]={width:me,height:Le}},km.calculateLabelAngle=function(x,m){var k=x._private,S=k.rscratch,M=x.isEdge(),O=m?m+"-":"",N=x.pstyle(O+"text-rotation"),$=N.strValue;return $==="none"?0:M&&$==="autorotate"?S.labelAutoAngle:$==="autorotate"?0:N.pfValue},km.calculateLabelAngles=function(x){var m=this,k=x.isEdge(),S=x._private,M=S.rscratch;M.labelAngle=m.calculateLabelAngle(x),k&&(M.sourceLabelAngle=m.calculateLabelAngle(x,"source"),M.targetLabelAngle=m.calculateLabelAngle(x,"target"))};var ez={},tz=28,nz=!1;ez.getNodeShape=function(x){var m=this,k=x.pstyle("shape").value;if(k==="cutrectangle"&&(x.width()1&&arguments[1]!==void 0?arguments[1]:!0;if(m.merge(N),$)for(var H=0;H=x.desktopTapThreshold2}var Wv=M(G);Wl&&(x.hoverData.tapholdCancelled=!0);var sy=function(){var Em=x.hoverData.dragDelta=x.hoverData.dragDelta||[];Em.length===0?(Em.push(xo[0]),Em.push(xo[1])):(Em[0]+=xo[0],Em[1]+=xo[1])};kr=!0,S(za,["mousemove","vmousemove","tapdrag"],G,{x:wr[0],y:wr[1]});var E8=function(){x.data.bgActivePosistion=void 0,x.hoverData.selecting||lr.emit({originalEvent:G,type:"boxstart",position:{x:wr[0],y:wr[1]}}),$c[4]=1,x.hoverData.selecting=!0,x.redrawHint("select",!0),x.redraw()};if(x.hoverData.which===3){if(Wl){var x5={originalEvent:G,type:"cxtdrag",position:{x:wr[0],y:wr[1]}};ba?ba.emit(x5):lr.emit(x5),x.hoverData.cxtDragged=!0,(!x.hoverData.cxtOver||za!==x.hoverData.cxtOver)&&(x.hoverData.cxtOver&&x.hoverData.cxtOver.emit({originalEvent:G,type:"cxtdragout",position:{x:wr[0],y:wr[1]}}),x.hoverData.cxtOver=za,za&&za.emit({originalEvent:G,type:"cxtdragover",position:{x:wr[0],y:wr[1]}}))}}else if(x.hoverData.dragging){if(kr=!0,lr.panningEnabled()&&lr.userPanningEnabled()){var T8;if(x.hoverData.justStartedPan){var ZS=x.hoverData.mdownPos;T8={x:(wr[0]-ZS[0])*Vt,y:(wr[1]-ZS[1])*Vt},x.hoverData.justStartedPan=!1}else T8={x:xo[0]*Vt,y:xo[1]*Vt};lr.panBy(T8),lr.emit("dragpan"),x.hoverData.dragged=!0}wr=x.projectIntoViewport(G.clientX,G.clientY)}else if($c[4]==1&&(ba==null||ba.pannable())){if(Wl){if(!x.hoverData.dragging&&lr.boxSelectionEnabled()&&(Wv||!lr.panningEnabled()||!lr.userPanningEnabled()))E8();else if(!x.hoverData.selecting&&lr.panningEnabled()&&lr.userPanningEnabled()){var k5=O(ba,x.hoverData.downs);k5&&(x.hoverData.dragging=!0,x.hoverData.justStartedPan=!0,$c[4]=0,x.data.bgActivePosistion=J7(Es),x.redrawHint("select",!0),x.redraw())}ba&&ba.pannable()&&ba.active()&&ba.unactivate()}}else{if(ba&&ba.pannable()&&ba.active()&&ba.unactivate(),(!ba||!ba.grabbed())&&za!=Sc&&(Sc&&S(Sc,["mouseout","tapdragout"],G,{x:wr[0],y:wr[1]}),za&&S(za,["mouseover","tapdragover"],G,{x:wr[0],y:wr[1]}),x.hoverData.last=za),ba)if(Wl){if(lr.boxSelectionEnabled()&&Wv)ba&&ba.grabbed()&&(_e(lh),ba.emit("freeon"),lh.emit("free"),x.dragData.didDrag&&(ba.emit("dragfreeon"),lh.emit("dragfree"))),E8();else if(ba&&ba.grabbed()&&x.nodeIsDraggable(ba)){var Qd=!x.dragData.didDrag;Qd&&x.redrawHint("eles",!0),x.dragData.didDrag=!0,x.hoverData.draggingEles||me(lh,{inDragLayer:!0});var _1={x:0,y:0};if(X(xo[0])&&X(xo[1])&&(_1.x+=xo[0],_1.y+=xo[1],Qd)){var Jd=x.hoverData.dragDelta;Jd&&X(Jd[0])&&X(Jd[1])&&(_1.x+=Jd[0],_1.y+=Jd[1])}x.hoverData.draggingEles=!0,lh.silentShift(_1).emit("position drag"),x.redrawHint("drag",!0),x.redraw()}}else sy();kr=!0}if($c[2]=wr[0],$c[3]=wr[1],kr)return G.stopPropagation&&G.stopPropagation(),G.preventDefault&&G.preventDefault(),!1}},!1);var Lt,Mt,ut;x.registerBinding(m,"mouseup",function(G){var Jn=x.hoverData.capture;if(Jn){x.hoverData.capture=!1;var kr=x.cy,lr=x.projectIntoViewport(G.clientX,G.clientY),Vt=x.selection,Hs=x.findNearestElement(lr[0],lr[1],!0,!1),wr=x.dragData.possibleDragElements,Es=x.hoverData.down,go=M(G);if(x.data.bgActivePosistion&&(x.redrawHint("select",!0),x.redraw()),x.hoverData.tapholdCancelled=!0,x.data.bgActivePosistion=void 0,Es&&Es.unactivate(),x.hoverData.which===3){var $c={originalEvent:G,type:"cxttapend",position:{x:lr[0],y:lr[1]}};if(Es?Es.emit($c):kr.emit($c),!x.hoverData.cxtDragged){var za={originalEvent:G,type:"cxttap",position:{x:lr[0],y:lr[1]}};Es?Es.emit(za):kr.emit(za)}x.hoverData.cxtDragged=!1,x.hoverData.which=null}else if(x.hoverData.which===1){if(S(Hs,["mouseup","tapend","vmouseup"],G,{x:lr[0],y:lr[1]}),!x.dragData.didDrag&&!x.hoverData.dragged&&!x.hoverData.selecting&&!x.hoverData.isOverThresholdDrag&&(S(Es,["click","tap","vclick"],G,{x:lr[0],y:lr[1]}),Mt=!1,G.timeStamp-ut<=kr.multiClickDebounceTime()?(Lt&&clearTimeout(Lt),Mt=!0,ut=null,S(Es,["dblclick","dbltap","vdblclick"],G,{x:lr[0],y:lr[1]})):(Lt=setTimeout(function(){Mt||S(Es,["oneclick","onetap","voneclick"],G,{x:lr[0],y:lr[1]})},kr.multiClickDebounceTime()),ut=G.timeStamp)),Es==null&&!x.dragData.didDrag&&!x.hoverData.selecting&&!x.hoverData.dragged&&!M(G)&&(kr.$(k).unselect(["tapunselect"]),wr.length>0&&x.redrawHint("eles",!0),x.dragData.possibleDragElements=wr=kr.collection()),Hs==Es&&!x.dragData.didDrag&&!x.hoverData.selecting&&Hs!=null&&Hs._private.selectable&&(x.hoverData.dragging||(kr.selectionType()==="additive"||go?Hs.selected()?Hs.unselect(["tapunselect"]):Hs.select(["tapselect"]):go||(kr.$(k).unmerge(Hs).unselect(["tapunselect"]),Hs.select(["tapselect"]))),x.redrawHint("eles",!0)),x.hoverData.selecting){var Sc=kr.collection(x.getAllInBox(Vt[0],Vt[1],Vt[2],Vt[3]));x.redrawHint("select",!0),Sc.length>0&&x.redrawHint("eles",!0),kr.emit({type:"boxend",originalEvent:G,position:{x:lr[0],y:lr[1]}});var ba=function(Wl){return Wl.selectable()&&!Wl.selected()};kr.selectionType()==="additive"||go||kr.$(k).unmerge(Sc).unselect(),Sc.emit("box").stdFilter(ba).select().emit("boxselect"),x.redraw()}if(x.hoverData.dragging&&(x.hoverData.dragging=!1,x.redrawHint("select",!0),x.redrawHint("eles",!0),x.redraw()),!Vt[4]){x.redrawHint("drag",!0),x.redrawHint("eles",!0);var xo=Es&&Es.grabbed();_e(wr),xo&&(Es.emit("freeon"),wr.emit("free"),x.dragData.didDrag&&(Es.emit("dragfreeon"),wr.emit("dragfree")))}}Vt[4]=0,x.hoverData.down=null,x.hoverData.cxtStarted=!1,x.hoverData.draggingEles=!1,x.hoverData.selecting=!1,x.hoverData.isOverThresholdDrag=!1,x.dragData.didDrag=!1,x.hoverData.dragged=!1,x.hoverData.dragDelta=[],x.hoverData.mdownPos=null,x.hoverData.mdownGPos=null}},!1);var Wt=function(G){if(!x.scrollingPage){var Jn=x.cy,kr=Jn.zoom(),lr=Jn.pan(),Vt=x.projectIntoViewport(G.clientX,G.clientY),Hs=[Vt[0]*kr+lr.x,Vt[1]*kr+lr.y];if(x.hoverData.draggingEles||x.hoverData.dragging||x.hoverData.cxtStarted||mt()){G.preventDefault();return}if(Jn.panningEnabled()&&Jn.userPanningEnabled()&&Jn.zoomingEnabled()&&Jn.userZoomingEnabled()){G.preventDefault(),x.data.wheelZooming=!0,clearTimeout(x.data.wheelTimeout),x.data.wheelTimeout=setTimeout(function(){x.data.wheelZooming=!1,x.redrawHint("eles",!0),x.redraw()},150);var wr;G.deltaY!=null?wr=G.deltaY/-250:G.wheelDeltaY!=null?wr=G.wheelDeltaY/1e3:wr=G.wheelDelta/1e3,wr=wr*x.wheelSensitivity;var Es=G.deltaMode===1;Es&&(wr*=33);var go=Jn.zoom()*Math.pow(10,wr);G.type==="gesturechange"&&(go=x.gestureStartZoom*G.scale),Jn.zoom({level:go,renderedPosition:{x:Hs[0],y:Hs[1]}}),Jn.emit(G.type==="gesturechange"?"pinchzoom":"scrollzoom")}}};x.registerBinding(x.container,"wheel",Wt,!0),x.registerBinding(m,"scroll",function(G){x.scrollingPage=!0,clearTimeout(x.scrollingPageTimeout),x.scrollingPageTimeout=setTimeout(function(){x.scrollingPage=!1},250)},!0),x.registerBinding(x.container,"gesturestart",function(G){x.gestureStartZoom=x.cy.zoom(),x.hasTouchStarted||G.preventDefault()},!0),x.registerBinding(x.container,"gesturechange",function(tr){x.hasTouchStarted||Wt(tr)},!0),x.registerBinding(x.container,"mouseout",function(G){var Jn=x.projectIntoViewport(G.clientX,G.clientY);x.cy.emit({originalEvent:G,type:"mouseout",position:{x:Jn[0],y:Jn[1]}})},!1),x.registerBinding(x.container,"mouseover",function(G){var Jn=x.projectIntoViewport(G.clientX,G.clientY);x.cy.emit({originalEvent:G,type:"mouseover",position:{x:Jn[0],y:Jn[1]}})},!1);var Tt,_n,hn,Yt,Dn,ir,vr,Nn,pr,Er,Mr,Cr,Or,Wn=function(G,Jn,kr,lr){return Math.sqrt((kr-G)*(kr-G)+(lr-Jn)*(lr-Jn))},br=function(G,Jn,kr,lr){return(kr-G)*(kr-G)+(lr-Jn)*(lr-Jn)},Sr;x.registerBinding(x.container,"touchstart",Sr=function(G){if(x.hasTouchStarted=!0,!!Je(G)){Be(),x.touchData.capture=!0,x.data.bgActivePosistion=void 0;var Jn=x.cy,kr=x.touchData.now,lr=x.touchData.earlier;if(G.touches[0]){var Vt=x.projectIntoViewport(G.touches[0].clientX,G.touches[0].clientY);kr[0]=Vt[0],kr[1]=Vt[1]}if(G.touches[1]){var Vt=x.projectIntoViewport(G.touches[1].clientX,G.touches[1].clientY);kr[2]=Vt[0],kr[3]=Vt[1]}if(G.touches[2]){var Vt=x.projectIntoViewport(G.touches[2].clientX,G.touches[2].clientY);kr[4]=Vt[0],kr[5]=Vt[1]}if(G.touches[1]){x.touchData.singleTouchMoved=!0,_e(x.dragData.touchDragEles);var Hs=x.findContainerClientCoords();pr=Hs[0],Er=Hs[1],Mr=Hs[2],Cr=Hs[3],Tt=G.touches[0].clientX-pr,_n=G.touches[0].clientY-Er,hn=G.touches[1].clientX-pr,Yt=G.touches[1].clientY-Er,Or=0<=Tt&&Tt<=Mr&&0<=hn&&hn<=Mr&&0<=_n&&_n<=Cr&&0<=Yt&&Yt<=Cr;var wr=Jn.pan(),Es=Jn.zoom();Dn=Wn(Tt,_n,hn,Yt),ir=br(Tt,_n,hn,Yt),vr=[(Tt+hn)/2,(_n+Yt)/2],Nn=[(vr[0]-wr.x)/Es,(vr[1]-wr.y)/Es];var go=200,$c=go*go;if(ir<$c&&!G.touches[2]){var za=x.findNearestElement(kr[0],kr[1],!0,!0),Sc=x.findNearestElement(kr[2],kr[3],!0,!0);za&&za.isNode()?(za.activate().emit({originalEvent:G,type:"cxttapstart",position:{x:kr[0],y:kr[1]}}),x.touchData.start=za):Sc&&Sc.isNode()?(Sc.activate().emit({originalEvent:G,type:"cxttapstart",position:{x:kr[0],y:kr[1]}}),x.touchData.start=Sc):Jn.emit({originalEvent:G,type:"cxttapstart",position:{x:kr[0],y:kr[1]}}),x.touchData.start&&(x.touchData.start._private.grabbed=!1),x.touchData.cxt=!0,x.touchData.cxtDragged=!1,x.data.bgActivePosistion=void 0,x.redraw();return}}if(G.touches[2])Jn.boxSelectionEnabled()&&G.preventDefault();else if(!G.touches[1]){if(G.touches[0]){var ba=x.findNearestElements(kr[0],kr[1],!0,!0),xo=ba[0];if(xo!=null&&(xo.activate(),x.touchData.start=xo,x.touchData.starts=ba,x.nodeIsGrabbable(xo))){var lh=x.dragData.touchDragEles=Jn.collection(),Wl=null;x.redrawHint("eles",!0),x.redrawHint("drag",!0),xo.selected()?(Wl=Jn.$(function(fd){return fd.selected()&&x.nodeIsGrabbable(fd)}),me(Wl,{addToList:lh})):Le(xo,{addToList:lh}),Y(xo);var Z2=function(Wv){return{originalEvent:G,type:Wv,position:{x:kr[0],y:kr[1]}}};xo.emit(Z2("grabon")),Wl?Wl.forEach(function(fd){fd.emit(Z2("grab"))}):xo.emit(Z2("grab"))}S(xo,["touchstart","tapstart","vmousedown"],G,{x:kr[0],y:kr[1]}),xo==null&&(x.data.bgActivePosistion={x:Vt[0],y:Vt[1]},x.redrawHint("select",!0),x.redraw()),x.touchData.singleTouchMoved=!1,x.touchData.singleTouchStartTime=+new Date,clearTimeout(x.touchData.tapholdTimeout),x.touchData.tapholdTimeout=setTimeout(function(){x.touchData.singleTouchMoved===!1&&!x.pinching&&!x.touchData.selecting&&S(x.touchData.start,["taphold"],G,{x:kr[0],y:kr[1]})},x.tapholdDuration)}}if(G.touches.length>=1){for(var eb=x.touchData.startPosition=[null,null,null,null,null,null],G0=0;G0=x.touchTapThreshold2}if(Jn&&x.touchData.cxt){G.preventDefault();var eb=G.touches[0].clientX-pr,G0=G.touches[0].clientY-Er,zp=G.touches[1].clientX-pr,fd=G.touches[1].clientY-Er,Wv=br(eb,G0,zp,fd),sy=Wv/ir,E8=150,x5=E8*E8,T8=1.5,ZS=T8*T8;if(sy>=ZS||Wv>=x5){x.touchData.cxt=!1,x.data.bgActivePosistion=void 0,x.redrawHint("select",!0);var k5={originalEvent:G,type:"cxttapend",position:{x:Vt[0],y:Vt[1]}};x.touchData.start?(x.touchData.start.unactivate().emit(k5),x.touchData.start=null):lr.emit(k5)}}if(Jn&&x.touchData.cxt){var k5={originalEvent:G,type:"cxtdrag",position:{x:Vt[0],y:Vt[1]}};x.data.bgActivePosistion=void 0,x.redrawHint("select",!0),x.touchData.start?x.touchData.start.emit(k5):lr.emit(k5),x.touchData.start&&(x.touchData.start._private.grabbed=!1),x.touchData.cxtDragged=!0;var Qd=x.findNearestElement(Vt[0],Vt[1],!0,!0);(!x.touchData.cxtOver||Qd!==x.touchData.cxtOver)&&(x.touchData.cxtOver&&x.touchData.cxtOver.emit({originalEvent:G,type:"cxtdragout",position:{x:Vt[0],y:Vt[1]}}),x.touchData.cxtOver=Qd,Qd&&Qd.emit({originalEvent:G,type:"cxtdragover",position:{x:Vt[0],y:Vt[1]}}))}else if(Jn&&G.touches[2]&&lr.boxSelectionEnabled())G.preventDefault(),x.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,x.touchData.selecting||lr.emit({originalEvent:G,type:"boxstart",position:{x:Vt[0],y:Vt[1]}}),x.touchData.selecting=!0,x.touchData.didSelect=!0,kr[4]=1,!kr||kr.length===0||kr[0]===void 0?(kr[0]=(Vt[0]+Vt[2]+Vt[4])/3,kr[1]=(Vt[1]+Vt[3]+Vt[5])/3,kr[2]=(Vt[0]+Vt[2]+Vt[4])/3+1,kr[3]=(Vt[1]+Vt[3]+Vt[5])/3+1):(kr[2]=(Vt[0]+Vt[2]+Vt[4])/3,kr[3]=(Vt[1]+Vt[3]+Vt[5])/3),x.redrawHint("select",!0),x.redraw();else if(Jn&&G.touches[1]&&!x.touchData.didSelect&&lr.zoomingEnabled()&&lr.panningEnabled()&&lr.userZoomingEnabled()&&lr.userPanningEnabled()){G.preventDefault(),x.data.bgActivePosistion=void 0,x.redrawHint("select",!0);var _1=x.dragData.touchDragEles;if(_1){x.redrawHint("drag",!0);for(var Jd=0;Jd<_1.length;Jd++){var Yv=_1[Jd]._private;Yv.grabbed=!1,Yv.rscratch.inDragLayer=!1}}var Em=x.touchData.start,eb=G.touches[0].clientX-pr,G0=G.touches[0].clientY-Er,zp=G.touches[1].clientX-pr,fd=G.touches[1].clientY-Er,Lz=Wn(eb,G0,zp,fd),Lie=Lz/Dn;if(Or){var Mie=eb-Tt,e_=G0-_n,Die=zp-hn,Iie=fd-Yt,E5=(Mie+Die)/2,Mz=(e_+Iie)/2,yk=lr.zoom(),UI=yk*Lie,t_=lr.pan(),Dz=Nn[0]*yk+t_.x,Iz=Nn[1]*yk+t_.y,Oie={x:-UI/yk*(Dz-t_.x-E5)+Dz,y:-UI/yk*(Iz-t_.y-Mz)+Iz};if(Em&&Em.active()){var _1=x.dragData.touchDragEles;_e(_1),x.redrawHint("drag",!0),x.redrawHint("eles",!0),Em.unactivate().emit("freeon"),_1.emit("free"),x.dragData.didDrag&&(Em.emit("dragfreeon"),_1.emit("dragfree"))}lr.viewport({zoom:UI,pan:Oie,cancelOnFailedZoom:!0}),lr.emit("pinchzoom"),Dn=Lz,Tt=eb,_n=G0,hn=zp,Yt=fd,x.pinching=!0}if(G.touches[0]){var Es=x.projectIntoViewport(G.touches[0].clientX,G.touches[0].clientY);Vt[0]=Es[0],Vt[1]=Es[1]}if(G.touches[1]){var Es=x.projectIntoViewport(G.touches[1].clientX,G.touches[1].clientY);Vt[2]=Es[0],Vt[3]=Es[1]}if(G.touches[2]){var Es=x.projectIntoViewport(G.touches[2].clientX,G.touches[2].clientY);Vt[4]=Es[0],Vt[5]=Es[1]}}else if(G.touches[0]&&!x.touchData.didSelect){var qp=x.touchData.start,n_=x.touchData.last,Qd;if(!x.hoverData.draggingEles&&!x.swipePanning&&(Qd=x.findNearestElement(Vt[0],Vt[1],!0,!0)),Jn&&qp!=null&&G.preventDefault(),Jn&&qp!=null&&x.nodeIsDraggable(qp))if($c){var _1=x.dragData.touchDragEles,GI=!x.dragData.didDrag;GI&&me(_1,{inDragLayer:!0}),x.dragData.didDrag=!0;var Tm={x:0,y:0};if(X(za[0])&&X(za[1])&&(Tm.x+=za[0],Tm.y+=za[1],GI)){x.redrawHint("eles",!0);var Zd=x.touchData.dragDelta;Zd&&X(Zd[0])&&X(Zd[1])&&(Tm.x+=Zd[0],Tm.y+=Zd[1])}x.hoverData.draggingEles=!0,_1.silentShift(Tm).emit("position drag"),x.redrawHint("drag",!0),x.touchData.startPosition[0]==Hs[0]&&x.touchData.startPosition[1]==Hs[1]&&x.redrawHint("eles",!0),x.redraw()}else{var Zd=x.touchData.dragDelta=x.touchData.dragDelta||[];Zd.length===0?(Zd.push(za[0]),Zd.push(za[1])):(Zd[0]+=za[0],Zd[1]+=za[1])}if(S(qp||Qd,["touchmove","tapdrag","vmousemove"],G,{x:Vt[0],y:Vt[1]}),(!qp||!qp.grabbed())&&Qd!=n_&&(n_&&n_.emit({originalEvent:G,type:"tapdragout",position:{x:Vt[0],y:Vt[1]}}),Qd&&Qd.emit({originalEvent:G,type:"tapdragover",position:{x:Vt[0],y:Vt[1]}})),x.touchData.last=Qd,Jn)for(var Jd=0;Jd0&&!x.hoverData.draggingEles&&!x.swipePanning&&x.data.bgActivePosistion!=null&&(x.data.bgActivePosistion=void 0,x.redrawHint("select",!0),x.redraw())}},!1);var Si;x.registerBinding(m,"touchcancel",Si=function(G){var Jn=x.touchData.start;x.touchData.capture=!1,Jn&&Jn.unactivate()});var ys,pa,Mi,gi;if(x.registerBinding(m,"touchend",ys=function(G){var Jn=x.touchData.start,kr=x.touchData.capture;if(kr)G.touches.length===0&&(x.touchData.capture=!1),G.preventDefault();else return;var lr=x.selection;x.swipePanning=!1,x.hoverData.draggingEles=!1;var Vt=x.cy,Hs=Vt.zoom(),wr=x.touchData.now,Es=x.touchData.earlier;if(G.touches[0]){var go=x.projectIntoViewport(G.touches[0].clientX,G.touches[0].clientY);wr[0]=go[0],wr[1]=go[1]}if(G.touches[1]){var go=x.projectIntoViewport(G.touches[1].clientX,G.touches[1].clientY);wr[2]=go[0],wr[3]=go[1]}if(G.touches[2]){var go=x.projectIntoViewport(G.touches[2].clientX,G.touches[2].clientY);wr[4]=go[0],wr[5]=go[1]}Jn&&Jn.unactivate();var $c;if(x.touchData.cxt){if($c={originalEvent:G,type:"cxttapend",position:{x:wr[0],y:wr[1]}},Jn?Jn.emit($c):Vt.emit($c),!x.touchData.cxtDragged){var za={originalEvent:G,type:"cxttap",position:{x:wr[0],y:wr[1]}};Jn?Jn.emit(za):Vt.emit(za)}x.touchData.start&&(x.touchData.start._private.grabbed=!1),x.touchData.cxt=!1,x.touchData.start=null,x.redraw();return}if(!G.touches[2]&&Vt.boxSelectionEnabled()&&x.touchData.selecting){x.touchData.selecting=!1;var Sc=Vt.collection(x.getAllInBox(lr[0],lr[1],lr[2],lr[3]));lr[0]=void 0,lr[1]=void 0,lr[2]=void 0,lr[3]=void 0,lr[4]=0,x.redrawHint("select",!0),Vt.emit({type:"boxend",originalEvent:G,position:{x:wr[0],y:wr[1]}});var ba=function(x5){return x5.selectable()&&!x5.selected()};Sc.emit("box").stdFilter(ba).select().emit("boxselect"),Sc.nonempty()&&x.redrawHint("eles",!0),x.redraw()}if(Jn!=null&&Jn.unactivate(),G.touches[2])x.data.bgActivePosistion=void 0,x.redrawHint("select",!0);else if(!G.touches[1]){if(!G.touches[0]){if(!G.touches[0]){x.data.bgActivePosistion=void 0,x.redrawHint("select",!0);var xo=x.dragData.touchDragEles;if(Jn!=null){var lh=Jn._private.grabbed;_e(xo),x.redrawHint("drag",!0),x.redrawHint("eles",!0),lh&&(Jn.emit("freeon"),xo.emit("free"),x.dragData.didDrag&&(Jn.emit("dragfreeon"),xo.emit("dragfree"))),S(Jn,["touchend","tapend","vmouseup","tapdragout"],G,{x:wr[0],y:wr[1]}),Jn.unactivate(),x.touchData.start=null}else{var Wl=x.findNearestElement(wr[0],wr[1],!0,!0);S(Wl,["touchend","tapend","vmouseup","tapdragout"],G,{x:wr[0],y:wr[1]})}var Z2=x.touchData.startPosition[0]-wr[0],eb=Z2*Z2,G0=x.touchData.startPosition[1]-wr[1],zp=G0*G0,fd=eb+zp,Wv=fd*Hs*Hs;x.touchData.singleTouchMoved||(Jn||Vt.$(":selected").unselect(["tapunselect"]),S(Jn,["tap","vclick"],G,{x:wr[0],y:wr[1]}),pa=!1,G.timeStamp-gi<=Vt.multiClickDebounceTime()?(Mi&&clearTimeout(Mi),pa=!0,gi=null,S(Jn,["dbltap","vdblclick"],G,{x:wr[0],y:wr[1]})):(Mi=setTimeout(function(){pa||S(Jn,["onetap","voneclick"],G,{x:wr[0],y:wr[1]})},Vt.multiClickDebounceTime()),gi=G.timeStamp)),Jn!=null&&!x.dragData.didDrag&&Jn._private.selectable&&Wv"u"){var fs=[],Fs=function(G){return{clientX:G.clientX,clientY:G.clientY,force:1,identifier:G.pointerId,pageX:G.pageX,pageY:G.pageY,radiusX:G.width/2,radiusY:G.height/2,screenX:G.screenX,screenY:G.screenY,target:G.target}},xs=function(G){return{event:G,touch:Fs(G)}},Rs=function(G){fs.push(xs(G))},yo=function(G){for(var Jn=0;Jn0)return Nn[0]}return null},ve=Object.keys(Z),me=0;me0?ce:bj(O,N,m,k,S,M,$)},checkPoint:function(m,k,S,M,O,N,$){var H=W9(M,O),q=2*H;if(Uv(m,k,this.points,N,$,M,O-q,[0,-1],S)||Uv(m,k,this.points,N,$,M-q,O,[0,-1],S))return!0;var Y=M/2+2*S,Z=O/2+2*S,ce=[N-Y,$-Z,N-Y,$,N+Y,$,N+Y,$-Z];return!!(Yd(m,k,ce)||d5(m,k,q,q,N+M/2-H,$+O/2-H,S)||d5(m,k,q,q,N-M/2+H,$+O/2-H,S))}}},Kv.registerNodeShapes=function(){var x=this.nodeShapes={},m=this;this.generateEllipse(),this.generatePolygon("triangle",hd(3,0)),this.generateRoundPolygon("round-triangle",hd(3,0)),this.generatePolygon("rectangle",hd(4,0)),x.square=x.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();{var k=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",k),this.generateRoundPolygon("round-diamond",k)}this.generatePolygon("pentagon",hd(5,0)),this.generateRoundPolygon("round-pentagon",hd(5,0)),this.generatePolygon("hexagon",hd(6,0)),this.generateRoundPolygon("round-hexagon",hd(6,0)),this.generatePolygon("heptagon",hd(7,0)),this.generateRoundPolygon("round-heptagon",hd(7,0)),this.generatePolygon("octagon",hd(8,0)),this.generateRoundPolygon("round-octagon",hd(8,0));var S=new Array(20);{var M=oI(5,0),O=oI(5,Math.PI/5),N=.5*(3-Math.sqrt(5));N*=1.57;for(var $=0;$=m.deqFastCost*Ve)break}else if(q){if(Be>=m.deqCost*ve||Be>=m.deqAvgCost*ce)break}else if(Re>=m.deqNoDrawCost*RI)break;var ct=m.deq(S,_e,Le);if(ct.length>0)for(var st=0;st0&&(m.onDeqd(S,me),!q&&m.shouldRedraw(S,me,_e,Le)&&O())},$=m.priority||nI;M.beforeRender(N,$(S))}}}},Ure=function(){function x(m){var k=arguments.length>1&&arguments[1]!==void 0?arguments[1]:X3;d(this,x),this.idsByKey=new wm,this.keyForId=new wm,this.cachesByLvl=new wm,this.lvls=[],this.getKey=m,this.doesEleInvalidateKey=k}return v(x,[{key:"getIdsFor",value:function(k){k==null&&ch("Can not get id list for null key");var S=this.idsByKey,M=this.idsByKey.get(k);return M||(M=new Q7,S.set(k,M)),M}},{key:"addIdForKey",value:function(k,S){k!=null&&this.getIdsFor(k).add(S)}},{key:"deleteIdForKey",value:function(k,S){k!=null&&this.getIdsFor(k).delete(S)}},{key:"getNumberOfIdsForKey",value:function(k){return k==null?0:this.getIdsFor(k).size}},{key:"updateKeyMappingFor",value:function(k){var S=k.id(),M=this.keyForId.get(S),O=this.getKey(k);this.deleteIdForKey(M,S),this.addIdForKey(O,S),this.keyForId.set(S,O)}},{key:"deleteKeyMappingFor",value:function(k){var S=k.id(),M=this.keyForId.get(S);this.deleteIdForKey(M,S),this.keyForId.delete(S)}},{key:"keyHasChangedFor",value:function(k){var S=k.id(),M=this.keyForId.get(S),O=this.getKey(k);return M!==O}},{key:"isInvalid",value:function(k){return this.keyHasChangedFor(k)||this.doesEleInvalidateKey(k)}},{key:"getCachesAt",value:function(k){var S=this.cachesByLvl,M=this.lvls,O=S.get(k);return O||(O=new wm,S.set(k,O),M.push(k)),O}},{key:"getCache",value:function(k,S){return this.getCachesAt(S).get(k)}},{key:"get",value:function(k,S){var M=this.getKey(k),O=this.getCache(M,S);return O!=null&&this.updateKeyMappingFor(k),O}},{key:"getForCachedKey",value:function(k,S){var M=this.keyForId.get(k.id()),O=this.getCache(M,S);return O}},{key:"hasCache",value:function(k,S){return this.getCachesAt(S).has(k)}},{key:"has",value:function(k,S){var M=this.getKey(k);return this.hasCache(M,S)}},{key:"setCache",value:function(k,S,M){M.key=k,this.getCachesAt(S).set(k,M)}},{key:"set",value:function(k,S,M){var O=this.getKey(k);this.setCache(O,S,M),this.updateKeyMappingFor(k)}},{key:"deleteCache",value:function(k,S){this.getCachesAt(S).delete(k)}},{key:"delete",value:function(k,S){var M=this.getKey(k);this.deleteCache(M,S)}},{key:"invalidateKey",value:function(k){var S=this;this.lvls.forEach(function(M){return S.deleteCache(k,M)})}},{key:"invalidate",value:function(k){var S=k.id(),M=this.keyForId.get(S);this.deleteKeyMappingFor(k);var O=this.doesEleInvalidateKey(k);return O&&this.invalidateKey(M),O||this.getNumberOfIdsForKey(M)===0}}]),x}(),cz=25,YS=50,XS=-4,jI=3,Gre=7.99,Kre=8,Wre=1024,Yre=1024,Xre=1024,Qre=.2,Jre=.8,Zre=10,eie=.15,tie=.1,nie=.9,rie=.9,iie=100,sie=1,v8={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},aie=q0({getKey:null,doesEleInvalidateKey:X3,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:l5,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),dk=function(m,k){var S=this;S.renderer=m,S.onDequeues=[];var M=aie(k);yt(S,M),S.lookup=new Ure(M.getKey,M.doesEleInvalidateKey),S.setupDequeueing()},Cf=dk.prototype;Cf.reasons=v8,Cf.getTextureQueue=function(x){var m=this;return m.eleImgCaches=m.eleImgCaches||{},m.eleImgCaches[x]=m.eleImgCaches[x]||[]},Cf.getRetiredTextureQueue=function(x){var m=this,k=m.eleImgCaches.retired=m.eleImgCaches.retired||{},S=k[x]=k[x]||[];return S},Cf.getElementQueue=function(){var x=this,m=x.eleCacheQueue=x.eleCacheQueue||new V9(function(k,S){return S.reqs-k.reqs});return m},Cf.getElementKeyToQueue=function(){var x=this,m=x.eleKeyToCacheQueue=x.eleKeyToCacheQueue||{};return m},Cf.getElement=function(x,m,k,S,M){var O=this,N=this.renderer,$=N.cy.zoom(),H=this.lookup;if(!m||m.w===0||m.h===0||isNaN(m.w)||isNaN(m.h)||!x.visible()||x.removed()||!O.allowEdgeTxrCaching&&x.isEdge()||!O.allowParentTxrCaching&&x.isParent())return null;if(S==null&&(S=Math.ceil(iI($*k))),S=Gre||S>jI)return null;var q=Math.pow(2,S),Y=m.h*q,Z=m.w*q,ce=N.eleTextBiggerThanMin(x,q);if(!this.isVisible(x,ce))return null;var ve=H.get(x,S);if(ve&&ve.invalidated&&(ve.invalidated=!1,ve.texture.invalidatedWidth-=ve.width),ve)return ve;var me;if(Y<=cz?me=cz:Y<=YS?me=YS:me=Math.ceil(Y/YS)*YS,Y>Xre||Z>Yre)return null;var Le=O.getTextureQueue(me),_e=Le[Le.length-2],Ee=function(){return O.recycleTexture(me,Z)||O.addTexture(me,Z)};_e||(_e=Le[Le.length-1]),_e||(_e=Ee()),_e.width-_e.usedWidthS;Mt--)Je=O.getElement(x,m,k,Mt,v8.downscale);Lt()}else return O.queueElement(x,st.level-1),st;else{var ut;if(!Re&&!Ve&&!ct)for(var Wt=S-1;Wt>=XS;Wt--){var Tt=H.get(x,Wt);if(Tt){ut=Tt;break}}if(Be(ut))return O.queueElement(x,S),ut;_e.context.translate(_e.usedWidth,0),_e.context.scale(q,q),this.drawElement(_e.context,x,m,ce,!1),_e.context.scale(1/q,1/q),_e.context.translate(-_e.usedWidth,0)}return ve={x:_e.usedWidth,texture:_e,level:S,scale:q,width:Z,height:Y,scaledLabelShown:ce},_e.usedWidth+=Math.ceil(Z+Kre),_e.eleCaches.push(ve),H.set(x,S,ve),O.checkTextureFullness(_e),ve},Cf.invalidateElements=function(x){for(var m=0;m=Qre*x.width&&this.retireTexture(x)},Cf.checkTextureFullness=function(x){var m=this,k=m.getTextureQueue(x.height);x.usedWidth/x.width>Jre&&x.fullnessChecks>=Zre?Q3(k,x):x.fullnessChecks++},Cf.retireTexture=function(x){var m=this,k=x.height,S=m.getTextureQueue(k),M=this.lookup;Q3(S,x),x.retired=!0;for(var O=x.eleCaches,N=0;N=m)return N.retired=!1,N.usedWidth=0,N.invalidatedWidth=0,N.fullnessChecks=0,cS(N.eleCaches),N.context.setTransform(1,0,0,1,0,0),N.context.clearRect(0,0,N.width,N.height),Q3(M,N),S.push(N),N}},Cf.queueElement=function(x,m){var k=this,S=k.getElementQueue(),M=k.getElementKeyToQueue(),O=this.getKey(x),N=M[O];if(N)N.level=Math.max(N.level,m),N.eles.merge(x),N.reqs++,S.updateItem(N);else{var $={eles:x.spawn().merge(x),level:m,reqs:1,key:O};S.push($),M[O]=$}},Cf.dequeue=function(x){for(var m=this,k=m.getElementQueue(),S=m.getElementKeyToQueue(),M=[],O=m.lookup,N=0;N0;N++){var $=k.pop(),H=$.key,q=$.eles[0],Y=O.hasCache(q,$.level);if(S[H]=null,Y)continue;M.push($);var Z=m.getBoundingBox(q);m.getElement(q,Z,x,$.level,v8.dequeue)}return M},Cf.removeFromQueue=function(x){var m=this,k=m.getElementQueue(),S=m.getElementKeyToQueue(),M=this.getKey(x),O=S[M];O!=null&&(O.eles.length===1?(O.reqs=X7,k.updateItem(O),k.pop(),S[M]=null):O.eles.unmerge(x))},Cf.onDequeue=function(x){this.onDequeues.push(x)},Cf.offDequeue=function(x){Q3(this.onDequeues,x)},Cf.setupDequeueing=oz.setupDequeueing({deqRedrawThreshold:iie,deqCost:eie,deqAvgCost:tie,deqNoDrawCost:nie,deqFastCost:rie,deq:function(m,k,S){return m.dequeue(k,S)},onDeqd:function(m,k){for(var S=0;S=cie||k>QS)return null}S.validateLayersElesOrdering(k,x);var H=S.layersByLevel,q=Math.pow(2,k),Y=H[k]=H[k]||[],Z,ce=S.levelIsComplete(k,x),ve,me=function(){var Lt=function(_n){if(S.validateLayersElesOrdering(_n,x),S.levelIsComplete(_n,x))return ve=H[_n],!0},Mt=function(_n){if(!ve)for(var hn=k+_n;gk<=hn&&hn<=QS&&!Lt(hn);hn+=_n);};Mt(1),Mt(-1);for(var ut=Y.length-1;ut>=0;ut--){var Wt=Y[ut];Wt.invalid&&Q3(Y,Wt)}};if(!ce)me();else return Y;var Le=function(){if(!Z){Z=Wd();for(var Lt=0;Lthz)return null;var Wt=S.makeLayer(Z,k);if(Mt!=null){var Tt=Y.indexOf(Mt)+1;Y.splice(Tt,0,Wt)}else(Lt.insert===void 0||Lt.insert)&&Y.unshift(Wt);return Wt};if(S.skipping&&!$)return null;for(var Ee=null,Be=x.length/oie,Re=!$,Ve=0;Ve=Be||!pj(Ee.bb,ct.boundingBox()))&&(Ee=_e({insert:!0,after:Ee}),!Ee))return null;ve||Re?S.queueLayer(Ee,ct):S.drawEleInLayer(Ee,ct,k,m),Ee.eles.push(ct),Ye[k]=Ee}return ve||(Re?null:Y)},n0.getEleLevelForLayerLevel=function(x,m){return x},n0.drawEleInLayer=function(x,m,k,S){var M=this,O=this.renderer,N=x.context,$=m.boundingBox();$.w===0||$.h===0||!m.visible()||(k=M.getEleLevelForLayerLevel(k,S),O.setImgSmoothing(N,!1),O.drawCachedElement(N,m,null,null,k,fz),O.setImgSmoothing(N,!0))},n0.levelIsComplete=function(x,m){var k=this,S=k.layersByLevel[x];if(!S||S.length===0)return!1;for(var M=0,O=0;O0||N.invalid)return!1;M+=N.eles.length}return M===m.length},n0.validateLayersElesOrdering=function(x,m){var k=this.layersByLevel[x];if(k)for(var S=0;S0){m=!0;break}}return m},n0.invalidateElements=function(x){var m=this;x.length!==0&&(m.lastInvalidationTime=Bp(),!(x.length===0||!m.haveLayers())&&m.updateElementsInLayers(x,function(S,M,O){m.invalidateLayer(S)}))},n0.invalidateLayer=function(x){if(this.lastInvalidationTime=Bp(),!x.invalid){var m=x.level,k=x.eles,S=this.layersByLevel[m];Q3(S,x),x.elesQueue=[],x.invalid=!0,x.replacement&&(x.replacement.invalid=!0);for(var M=0;M3&&arguments[3]!==void 0?arguments[3]:!0,M=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,O=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,N=this,$=m._private.rscratch;if(!(O&&!m.visible())&&!($.badLine||$.allpts==null||isNaN($.allpts[0]))){var H;k&&(H=k,x.translate(-H.x1,-H.y1));var q=O?m.pstyle("opacity").value:1,Y=O?m.pstyle("line-opacity").value:1,Z=m.pstyle("curve-style").value,ce=m.pstyle("line-style").value,ve=m.pstyle("width").pfValue,me=m.pstyle("line-cap").value,Le=q*Y,_e=q*Y,Ee=function(){var ut=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Le;Z==="straight-triangle"?(N.eleStrokeStyle(x,m,ut),N.drawEdgeTrianglePath(m,x,$.allpts)):(x.lineWidth=ve,x.lineCap=me,N.eleStrokeStyle(x,m,ut),N.drawEdgePath(m,x,$.allpts,ce),x.lineCap="butt")},Be=function(){M&&N.drawEdgeOverlay(x,m)},Re=function(){M&&N.drawEdgeUnderlay(x,m)},Ve=function(){var ut=arguments.length>0&&arguments[0]!==void 0?arguments[0]:_e;N.drawArrowheads(x,m,ut)},ct=function(){N.drawElementText(x,m,null,S)};x.lineJoin="round";var st=m.pstyle("ghost").value==="yes";if(st){var Ye=m.pstyle("ghost-offset-x").pfValue,mt=m.pstyle("ghost-offset-y").pfValue,Je=m.pstyle("ghost-opacity").value,Lt=Le*Je;x.translate(Ye,mt),Ee(Lt),Ve(Lt),x.translate(-Ye,-mt)}Re(),Ee(),Ve(),Be(),ct(),k&&x.translate(H.x1,H.y1)}};var wz=function(m){if(!["overlay","underlay"].includes(m))throw new Error("Invalid state");return function(k,S){if(S.visible()){var M=S.pstyle("".concat(m,"-opacity")).value;if(M!==0){var O=this,N=O.usePaths(),$=S._private.rscratch,H=S.pstyle("".concat(m,"-padding")).pfValue,q=2*H,Y=S.pstyle("".concat(m,"-color")).value;k.lineWidth=q,$.edgeType==="self"&&!N?k.lineCap="butt":k.lineCap="round",O.colorStrokeStyle(k,Y[0],Y[1],Y[2],M),O.drawEdgePath(S,k,$.allpts,"solid")}}}};J2.drawEdgeOverlay=wz("overlay"),J2.drawEdgeUnderlay=wz("underlay"),J2.drawEdgePath=function(x,m,k,S){var M=x._private.rscratch,O=m,N,$=!1,H=this.usePaths(),q=x.pstyle("line-dash-pattern").pfValue,Y=x.pstyle("line-dash-offset").pfValue;if(H){var Z=k.join("$"),ce=M.pathCacheKey&&M.pathCacheKey===Z;ce?(N=m=M.pathCache,$=!0):(N=m=new Path2D,M.pathCacheKey=Z,M.pathCache=N)}if(O.setLineDash)switch(S){case"dotted":O.setLineDash([1,1]);break;case"dashed":O.setLineDash(q),O.lineDashOffset=Y;break;case"solid":O.setLineDash([]);break}if(!$&&!M.badLine)switch(m.beginPath&&m.beginPath(),m.moveTo(k[0],k[1]),M.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var ve=2;ve+35&&arguments[5]!==void 0?arguments[5]:!0,N=this;if(S==null){if(O&&!N.eleTextBiggerThanMin(m))return}else if(S===!1)return;if(m.isNode()){var $=m.pstyle("label");if(!$||!$.value)return;var H=N.getLabelJustification(m);x.textAlign=H,x.textBaseline="bottom"}else{var q=m.element()._private.rscratch.badLine,Y=m.pstyle("label"),Z=m.pstyle("source-label"),ce=m.pstyle("target-label");if(q||(!Y||!Y.value)&&(!Z||!Z.value)&&(!ce||!ce.value))return;x.textAlign="center",x.textBaseline="bottom"}var ve=!k,me;k&&(me=k,x.translate(-me.x1,-me.y1)),M==null?(N.drawText(x,m,null,ve,O),m.isEdge()&&(N.drawText(x,m,"source",ve,O),N.drawText(x,m,"target",ve,O))):N.drawText(x,m,M,ve,O),k&&x.translate(me.x1,me.y1)},y5.getFontCache=function(x){var m;this.fontCaches=this.fontCaches||[];for(var k=0;k2&&arguments[2]!==void 0?arguments[2]:!0,S=m.pstyle("font-style").strValue,M=m.pstyle("font-size").pfValue+"px",O=m.pstyle("font-family").strValue,N=m.pstyle("font-weight").strValue,$=k?m.effectiveOpacity()*m.pstyle("text-opacity").value:1,H=m.pstyle("text-outline-opacity").value*$,q=m.pstyle("color").value,Y=m.pstyle("text-outline-color").value;x.font=S+" "+N+" "+M+" "+O,x.lineJoin="round",this.colorFillStyle(x,q[0],q[1],q[2],$),this.colorStrokeStyle(x,Y[0],Y[1],Y[2],H)};function zI(x,m,k,S,M){var O=arguments.length>5&&arguments[5]!==void 0?arguments[5]:5,N=arguments.length>6?arguments[6]:void 0;x.beginPath(),x.moveTo(m+O,k),x.lineTo(m+S-O,k),x.quadraticCurveTo(m+S,k,m+S,k+O),x.lineTo(m+S,k+M-O),x.quadraticCurveTo(m+S,k+M,m+S-O,k+M),x.lineTo(m+O,k+M),x.quadraticCurveTo(m,k+M,m,k+M-O),x.lineTo(m,k+O),x.quadraticCurveTo(m,k,m+O,k),x.closePath(),N?x.stroke():x.fill()}y5.getTextAngle=function(x,m){var k,S=x._private,M=S.rscratch,O=m?m+"-":"",N=x.pstyle(O+"text-rotation"),$=K2(M,"labelAngle",m);return N.strValue==="autorotate"?k=x.isEdge()?$:0:N.strValue==="none"?k=0:k=N.pfValue,k},y5.drawText=function(x,m,k){var S=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,M=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,O=m._private,N=O.rscratch,$=M?m.effectiveOpacity():1;if(!(M&&($===0||m.pstyle("text-opacity").value===0))){k==="main"&&(k=null);var H=K2(N,"labelX",k),q=K2(N,"labelY",k),Y,Z,ce=this.getLabelText(m,k);if(ce!=null&&ce!==""&&!isNaN(H)&&!isNaN(q)){this.setupTextStyle(x,m,M);var ve=k?k+"-":"",me=K2(N,"labelWidth",k),Le=K2(N,"labelHeight",k),_e=m.pstyle(ve+"text-margin-x").pfValue,Ee=m.pstyle(ve+"text-margin-y").pfValue,Be=m.isEdge(),Re=m.pstyle("text-halign").value,Ve=m.pstyle("text-valign").value;Be&&(Re="center",Ve="center"),H+=_e,q+=Ee;var ct;switch(S?ct=this.getTextAngle(m,k):ct=0,ct!==0&&(Y=H,Z=q,x.translate(Y,Z),x.rotate(ct),H=0,q=0),Ve){case"top":break;case"center":q+=Le/2;break;case"bottom":q+=Le;break}var st=m.pstyle("text-background-opacity").value,Ye=m.pstyle("text-border-opacity").value,mt=m.pstyle("text-border-width").pfValue,Je=m.pstyle("text-background-padding").pfValue,Lt=m.pstyle("text-background-shape").strValue,Mt=Lt.indexOf("round")===0,ut=2;if(st>0||mt>0&&Ye>0){var Wt=H-Je;switch(Re){case"left":Wt-=me;break;case"center":Wt-=me/2;break}var Tt=q-Le-Je,_n=me+2*Je,hn=Le+2*Je;if(st>0){var Yt=x.fillStyle,Dn=m.pstyle("text-background-color").value;x.fillStyle="rgba("+Dn[0]+","+Dn[1]+","+Dn[2]+","+st*$+")",Mt?zI(x,Wt,Tt,_n,hn,ut):x.fillRect(Wt,Tt,_n,hn),x.fillStyle=Yt}if(mt>0&&Ye>0){var ir=x.strokeStyle,vr=x.lineWidth,Nn=m.pstyle("text-border-color").value,pr=m.pstyle("text-border-style").value;if(x.strokeStyle="rgba("+Nn[0]+","+Nn[1]+","+Nn[2]+","+Ye*$+")",x.lineWidth=mt,x.setLineDash)switch(pr){case"dotted":x.setLineDash([1,1]);break;case"dashed":x.setLineDash([4,2]);break;case"double":x.lineWidth=mt/4,x.setLineDash([]);break;case"solid":x.setLineDash([]);break}if(Mt?zI(x,Wt,Tt,_n,hn,ut,"stroke"):x.strokeRect(Wt,Tt,_n,hn),pr==="double"){var Er=mt/2;Mt?zI(x,Wt+Er,Tt+Er,_n-Er*2,hn-Er*2,ut,"stroke"):x.strokeRect(Wt+Er,Tt+Er,_n-Er*2,hn-Er*2)}x.setLineDash&&x.setLineDash([]),x.lineWidth=vr,x.strokeStyle=ir}}var Mr=2*m.pstyle("text-outline-width").pfValue;if(Mr>0&&(x.lineWidth=Mr),m.pstyle("text-wrap").value==="wrap"){var Cr=K2(N,"labelWrapCachedLines",k),Or=K2(N,"labelLineHeight",k),Wn=me/2,br=this.getLabelJustification(m);switch(br==="auto"||(Re==="left"?br==="left"?H+=-me:br==="center"&&(H+=-Wn):Re==="center"?br==="left"?H+=-Wn:br==="right"&&(H+=Wn):Re==="right"&&(br==="center"?H+=Wn:br==="right"&&(H+=me))),Ve){case"top":q-=(Cr.length-1)*Or;break;case"center":case"bottom":q-=(Cr.length-1)*Or;break}for(var Sr=0;Sr0&&x.strokeText(Cr[Sr],H,q),x.fillText(Cr[Sr],H,q),q+=Or}else Mr>0&&x.strokeText(ce,H,q),x.fillText(ce,H,q);ct!==0&&(x.rotate(-ct),x.translate(-Y,-Z))}}};var w8={};w8.drawNode=function(x,m,k){var S=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,M=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,O=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,N=this,$,H,q=m._private,Y=q.rscratch,Z=m.position();if(!(!X(Z.x)||!X(Z.y))&&!(O&&!m.visible())){var ce=O?m.effectiveOpacity():1,ve=N.usePaths(),me,Le=!1,_e=m.padding();$=m.width()+2*_e,H=m.height()+2*_e;var Ee;k&&(Ee=k,x.translate(-Ee.x1,-Ee.y1));for(var Be=m.pstyle("background-image"),Re=Be.value,Ve=new Array(Re.length),ct=new Array(Re.length),st=0,Ye=0;Ye0&&arguments[0]!==void 0?arguments[0]:Wt;N.eleFillStyle(x,m,tr)},Er=function(){var tr=arguments.length>0&&arguments[0]!==void 0?arguments[0]:hn;N.colorStrokeStyle(x,Tt[0],Tt[1],Tt[2],tr)},Mr=function(){var tr=arguments.length>0&&arguments[0]!==void 0?arguments[0]:vr;N.colorStrokeStyle(x,Dn[0],Dn[1],Dn[2],tr)},Cr=function(tr,G,Jn,kr){var lr=N.nodePathCache=N.nodePathCache||[],Vt=ld(Jn==="polygon"?Jn+","+kr.join(","):Jn,""+G,""+tr),Hs=lr[Vt],wr,Es=!1;return Hs!=null?(wr=Hs,Es=!0,Y.pathCache=wr):(wr=new Path2D,lr[Vt]=Y.pathCache=wr),{path:wr,cacheHit:Es}},Or=m.pstyle("shape").strValue,Wn=m.pstyle("shape-polygon-points").pfValue;if(ve){x.translate(Z.x,Z.y);var br=Cr($,H,Or,Wn);me=br.path,Le=br.cacheHit}var Sr=function(){if(!Le){var tr=Z;ve&&(tr={x:0,y:0}),N.nodeShapes[N.getNodeShape(m)].draw(me||x,tr.x,tr.y,$,H)}ve?x.fill(me):x.fill()},Nr=function(){for(var tr=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ce,G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,Jn=q.backgrounding,kr=0,lr=0;lr0&&arguments[0]!==void 0?arguments[0]:!1,G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:ce;N.hasPie(m)&&(N.drawPie(x,m,G),tr&&(ve||N.nodeShapes[N.getNodeShape(m)].draw(x,Z.x,Z.y,$,H)))},ys=function(){var tr=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ce,G=(Mt>0?Mt:-Mt)*tr,Jn=Mt>0?0:255;Mt!==0&&(N.colorFillStyle(x,Jn,Jn,Jn,G),ve?x.fill(me):x.fill())},pa=function(){if(ut>0){if(x.lineWidth=ut,x.lineCap="butt",x.setLineDash)switch(_n){case"dotted":x.setLineDash([1,1]);break;case"dashed":x.setLineDash([4,2]);break;case"solid":case"double":x.setLineDash([]);break}if(ve?x.stroke(me):x.stroke(),_n==="double"){x.lineWidth=ut/3;var tr=x.globalCompositeOperation;x.globalCompositeOperation="destination-out",ve?x.stroke(me):x.stroke(),x.globalCompositeOperation=tr}x.setLineDash&&x.setLineDash([])}},Mi=function(){if(Yt>0){if(x.lineWidth=Yt,x.lineCap="butt",x.setLineDash)switch(ir){case"dotted":x.setLineDash([1,1]);break;case"dashed":x.setLineDash([4,2]);break;case"solid":case"double":x.setLineDash([]);break}var tr=Z;ve&&(tr={x:0,y:0});var G=N.getNodeShape(m),Jn=($+ut+(Yt+Nn))/$,kr=(H+ut+(Yt+Nn))/H,lr=$*Jn,Vt=H*kr,Hs=N.nodeShapes[G].points,wr;if(ve){var Es=Cr(lr,Vt,G,Hs);wr=Es.path}if(G==="ellipse")N.drawEllipsePath(wr||x,tr.x,tr.y,lr,Vt);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(G)){var go=0,$c=0,za=0;G==="round-diamond"?go=(ut+Nn+Yt)*1.4:G==="round-heptagon"?(go=(ut+Nn+Yt)*1.075,za=-(ut/2+Nn+Yt)/35):G==="round-hexagon"?go=(ut+Nn+Yt)*1.12:G==="round-pentagon"?(go=(ut+Nn+Yt)*1.13,za=-(ut/2+Nn+Yt)/15):G==="round-tag"?(go=(ut+Nn+Yt)*1.12,$c=(ut/2+Yt+Nn)*.07):G==="round-triangle"&&(go=(ut+Nn+Yt)*(Math.PI/2),za=-(ut+Nn/2+Yt)/Math.PI),go!==0&&(Jn=($+go)/$,kr=(H+go)/H),N.drawRoundPolygonPath(wr||x,tr.x+$c,tr.y+za,$*Jn,H*kr,Hs)}else if(["roundrectangle","round-rectangle"].includes(G))N.drawRoundRectanglePath(wr||x,tr.x,tr.y,lr,Vt);else if(["cutrectangle","cut-rectangle"].includes(G))N.drawCutRectanglePath(wr||x,tr.x,tr.y,lr,Vt);else if(["bottomroundrectangle","bottom-round-rectangle"].includes(G))N.drawBottomRoundRectanglePath(wr||x,tr.x,tr.y,lr,Vt);else if(G==="barrel")N.drawBarrelPath(wr||x,tr.x,tr.y,lr,Vt);else if(G.startsWith("polygon")||["rhomboid","right-rhomboid","round-tag","tag","vee"].includes(G)){var Sc=(ut+Yt+Nn)/$;Hs=gS(pS(Hs,Sc)),N.drawPolygonPath(wr||x,tr.x,tr.y,$,H,Hs)}else{var ba=(ut+Yt+Nn)/$;Hs=gS(pS(Hs,-ba)),N.drawPolygonPath(wr||x,tr.x,tr.y,$,H,Hs)}if(ve?x.stroke(wr):x.stroke(),ir==="double"){x.lineWidth=ut/3;var xo=x.globalCompositeOperation;x.globalCompositeOperation="destination-out",ve?x.stroke(wr):x.stroke(),x.globalCompositeOperation=xo}x.setLineDash&&x.setLineDash([])}},gi=function(){M&&N.drawNodeOverlay(x,m,Z,$,H)},fs=function(){M&&N.drawNodeUnderlay(x,m,Z,$,H)},Fs=function(){N.drawElementText(x,m,null,S)},xs=m.pstyle("ghost").value==="yes";if(xs){var Rs=m.pstyle("ghost-offset-x").pfValue,yo=m.pstyle("ghost-offset-y").pfValue,$a=m.pstyle("ghost-opacity").value,Da=$a*ce;x.translate(Rs,yo),Mr(),Mi(),pr($a*Wt),Sr(),Nr(Da,!0),Er($a*hn),pa(),Si(Mt!==0||ut!==0),Nr(Da,!1),ys(Da),x.translate(-Rs,-yo)}ve&&x.translate(-Z.x,-Z.y),fs(),ve&&x.translate(Z.x,Z.y),Mr(),Mi(),pr(),Sr(),Nr(ce,!0),Er(),pa(),Si(Mt!==0||ut!==0),Nr(ce,!1),ys(),ve&&x.translate(-Z.x,-Z.y),Fs(),gi(),k&&x.translate(Ee.x1,Ee.y1)}};var qI=function(m){if(!["overlay","underlay"].includes(m))throw new Error("Invalid state");return function(k,S,M,O,N){var $=this;if(S.visible()){var H=S.pstyle("".concat(m,"-padding")).pfValue,q=S.pstyle("".concat(m,"-opacity")).value,Y=S.pstyle("".concat(m,"-color")).value,Z=S.pstyle("".concat(m,"-shape")).value;if(q>0){if(M=M||S.position(),O==null||N==null){var ce=S.padding();O=S.width()+2*ce,N=S.height()+2*ce}$.colorFillStyle(k,Y[0],Y[1],Y[2],q),$.nodeShapes[Z].draw(k,M.x,M.y,O+H*2,N+H*2),k.fill()}}}};w8.drawNodeOverlay=qI("overlay"),w8.drawNodeUnderlay=qI("underlay"),w8.hasPie=function(x){return x=x[0],x._private.hasPie},w8.drawPie=function(x,m,k,S){m=m[0],S=S||m.position();var M=m.cy().style(),O=m.pstyle("pie-size"),N=S.x,$=S.y,H=m.width(),q=m.height(),Y=Math.min(H,q)/2,Z=0,ce=this.usePaths();ce&&(N=0,$=0),O.units==="%"?Y=Y*O.pfValue:O.pfValue!==void 0&&(Y=O.pfValue/2);for(var ve=1;ve<=M.pieBackgroundN;ve++){var me=m.pstyle("pie-"+ve+"-background-size").value,Le=m.pstyle("pie-"+ve+"-background-color").value,_e=m.pstyle("pie-"+ve+"-background-opacity").value*k,Ee=me/100;Ee+Z>1&&(Ee=1-Z);var Be=1.5*Math.PI+2*Math.PI*Z,Re=2*Math.PI*Ee,Ve=Be+Re;me===0||Z>=1||Z+Ee>1||(x.beginPath(),x.moveTo(N,$),x.arc(N,$,Y,Be,Ve),x.closePath(),this.colorFillStyle(x,Le[0],Le[1],Le[2],_e),x.fill(),Z+=Ee)}};var qg={},xie=100;qg.getPixelRatio=function(){var x=this.data.contexts[0];if(this.forcedPixelRatio!=null)return this.forcedPixelRatio;var m=x.backingStorePixelRatio||x.webkitBackingStorePixelRatio||x.mozBackingStorePixelRatio||x.msBackingStorePixelRatio||x.oBackingStorePixelRatio||x.backingStorePixelRatio||1;return(window.devicePixelRatio||1)/m},qg.paintCache=function(x){for(var m=this.paintCaches=this.paintCaches||[],k=!0,S,M=0;MN.minMbLowQualFrames&&(N.motionBlurPxRatio=N.mbPxRBlurry)),N.clearingMotionBlur&&(N.motionBlurPxRatio=1),N.textureDrawLastFrame&&!Z&&(Y[N.NODE]=!0,Y[N.SELECT_BOX]=!0);var Be=H.style(),Re=H.zoom(),Ve=M!==void 0?M:Re,ct=H.pan(),st={x:ct.x,y:ct.y},Ye={zoom:Re,pan:{x:ct.x,y:ct.y}},mt=N.prevViewport,Je=mt===void 0||Ye.zoom!==mt.zoom||Ye.pan.x!==mt.pan.x||Ye.pan.y!==mt.pan.y;!Je&&!(Le&&!me)&&(N.motionBlurPxRatio=1),O&&(st=O),Ve*=$,st.x*=$,st.y*=$;var Lt=N.getCachedZSortedEles();function Mt(Mi,gi,fs,Fs,xs){var Rs=Mi.globalCompositeOperation;Mi.globalCompositeOperation="destination-out",N.colorFillStyle(Mi,255,255,255,N.motionBlurTransparency),Mi.fillRect(gi,fs,Fs,xs),Mi.globalCompositeOperation=Rs}function ut(Mi,gi){var fs,Fs,xs,Rs;!N.clearingMotionBlur&&(Mi===q.bufferContexts[N.MOTIONBLUR_BUFFER_NODE]||Mi===q.bufferContexts[N.MOTIONBLUR_BUFFER_DRAG])?(fs={x:ct.x*ve,y:ct.y*ve},Fs=Re*ve,xs=N.canvasWidth*ve,Rs=N.canvasHeight*ve):(fs=st,Fs=Ve,xs=N.canvasWidth,Rs=N.canvasHeight),Mi.setTransform(1,0,0,1,0,0),gi==="motionBlur"?Mt(Mi,0,0,xs,Rs):!m&&(gi===void 0||gi)&&Mi.clearRect(0,0,xs,Rs),k||(Mi.translate(fs.x,fs.y),Mi.scale(Fs,Fs)),O&&Mi.translate(O.x,O.y),M&&Mi.scale(M,M)}if(Z||(N.textureDrawLastFrame=!1),Z){if(N.textureDrawLastFrame=!0,!N.textureCache){N.textureCache={},N.textureCache.bb=H.mutableElements().boundingBox(),N.textureCache.texture=N.data.bufferCanvases[N.TEXTURE_BUFFER];var Wt=N.data.bufferContexts[N.TEXTURE_BUFFER];Wt.setTransform(1,0,0,1,0,0),Wt.clearRect(0,0,N.canvasWidth*N.textureMult,N.canvasHeight*N.textureMult),N.render({forcedContext:Wt,drawOnlyNodeLayer:!0,forcedPxRatio:$*N.textureMult});var Ye=N.textureCache.viewport={zoom:H.zoom(),pan:H.pan(),width:N.canvasWidth,height:N.canvasHeight};Ye.mpan={x:(0-Ye.pan.x)/Ye.zoom,y:(0-Ye.pan.y)/Ye.zoom}}Y[N.DRAG]=!1,Y[N.NODE]=!1;var Tt=q.contexts[N.NODE],_n=N.textureCache.texture,Ye=N.textureCache.viewport;Tt.setTransform(1,0,0,1,0,0),ce?Mt(Tt,0,0,Ye.width,Ye.height):Tt.clearRect(0,0,Ye.width,Ye.height);var hn=Be.core("outside-texture-bg-color").value,Yt=Be.core("outside-texture-bg-opacity").value;N.colorFillStyle(Tt,hn[0],hn[1],hn[2],Yt),Tt.fillRect(0,0,Ye.width,Ye.height);var Re=H.zoom();ut(Tt,!1),Tt.clearRect(Ye.mpan.x,Ye.mpan.y,Ye.width/Ye.zoom/$,Ye.height/Ye.zoom/$),Tt.drawImage(_n,Ye.mpan.x,Ye.mpan.y,Ye.width/Ye.zoom/$,Ye.height/Ye.zoom/$)}else N.textureOnViewport&&!m&&(N.textureCache=null);var Dn=H.extent(),ir=N.pinching||N.hoverData.dragging||N.swipePanning||N.data.wheelZooming||N.hoverData.draggingEles||N.cy.animated(),vr=N.hideEdgesOnViewport&&ir,Nn=[];if(Nn[N.NODE]=!Y[N.NODE]&&ce&&!N.clearedForMotionBlur[N.NODE]||N.clearingMotionBlur,Nn[N.NODE]&&(N.clearedForMotionBlur[N.NODE]=!0),Nn[N.DRAG]=!Y[N.DRAG]&&ce&&!N.clearedForMotionBlur[N.DRAG]||N.clearingMotionBlur,Nn[N.DRAG]&&(N.clearedForMotionBlur[N.DRAG]=!0),Y[N.NODE]||k||S||Nn[N.NODE]){var pr=ce&&!Nn[N.NODE]&&ve!==1,Tt=m||(pr?N.data.bufferContexts[N.MOTIONBLUR_BUFFER_NODE]:q.contexts[N.NODE]),Er=ce&&!pr?"motionBlur":void 0;ut(Tt,Er),vr?N.drawCachedNodes(Tt,Lt.nondrag,$,Dn):N.drawLayeredElements(Tt,Lt.nondrag,$,Dn),N.debug&&N.drawDebugPoints(Tt,Lt.nondrag),!k&&!ce&&(Y[N.NODE]=!1)}if(!S&&(Y[N.DRAG]||k||Nn[N.DRAG])){var pr=ce&&!Nn[N.DRAG]&&ve!==1,Tt=m||(pr?N.data.bufferContexts[N.MOTIONBLUR_BUFFER_DRAG]:q.contexts[N.DRAG]);ut(Tt,ce&&!pr?"motionBlur":void 0),vr?N.drawCachedNodes(Tt,Lt.drag,$,Dn):N.drawCachedElements(Tt,Lt.drag,$,Dn),N.debug&&N.drawDebugPoints(Tt,Lt.drag),!k&&!ce&&(Y[N.DRAG]=!1)}if(N.showFps||!S&&Y[N.SELECT_BOX]&&!k){var Tt=m||q.contexts[N.SELECT_BOX];if(ut(Tt),N.selection[4]==1&&(N.hoverData.selecting||N.touchData.selecting)){var Re=N.cy.zoom(),Mr=Be.core("selection-box-border-width").value/Re;Tt.lineWidth=Mr,Tt.fillStyle="rgba("+Be.core("selection-box-color").value[0]+","+Be.core("selection-box-color").value[1]+","+Be.core("selection-box-color").value[2]+","+Be.core("selection-box-opacity").value+")",Tt.fillRect(N.selection[0],N.selection[1],N.selection[2]-N.selection[0],N.selection[3]-N.selection[1]),Mr>0&&(Tt.strokeStyle="rgba("+Be.core("selection-box-border-color").value[0]+","+Be.core("selection-box-border-color").value[1]+","+Be.core("selection-box-border-color").value[2]+","+Be.core("selection-box-opacity").value+")",Tt.strokeRect(N.selection[0],N.selection[1],N.selection[2]-N.selection[0],N.selection[3]-N.selection[1]))}if(q.bgActivePosistion&&!N.hoverData.selecting){var Re=N.cy.zoom(),Cr=q.bgActivePosistion;Tt.fillStyle="rgba("+Be.core("active-bg-color").value[0]+","+Be.core("active-bg-color").value[1]+","+Be.core("active-bg-color").value[2]+","+Be.core("active-bg-opacity").value+")",Tt.beginPath(),Tt.arc(Cr.x,Cr.y,Be.core("active-bg-size").pfValue/Re,0,2*Math.PI),Tt.fill()}var Or=N.lastRedrawTime;if(N.showFps&&Or){Or=Math.round(Or);var Wn=Math.round(1e3/Or);Tt.setTransform(1,0,0,1,0,0),Tt.fillStyle="rgba(255, 0, 0, 0.75)",Tt.strokeStyle="rgba(255, 0, 0, 0.75)",Tt.lineWidth=1,Tt.fillText("1 frame = "+Or+" ms = "+Wn+" fps",0,20);var br=60;Tt.strokeRect(0,30,250,20),Tt.fillRect(0,30,250*Math.min(Wn/br,1),20)}k||(Y[N.SELECT_BOX]=!1)}if(ce&&ve!==1){var Sr=q.contexts[N.NODE],Nr=N.data.bufferCanvases[N.MOTIONBLUR_BUFFER_NODE],Si=q.contexts[N.DRAG],ys=N.data.bufferCanvases[N.MOTIONBLUR_BUFFER_DRAG],pa=function(gi,fs,Fs){gi.setTransform(1,0,0,1,0,0),Fs||!Ee?gi.clearRect(0,0,N.canvasWidth,N.canvasHeight):Mt(gi,0,0,N.canvasWidth,N.canvasHeight);var xs=ve;gi.drawImage(fs,0,0,N.canvasWidth*xs,N.canvasHeight*xs,0,0,N.canvasWidth,N.canvasHeight)};(Y[N.NODE]||Nn[N.NODE])&&(pa(Sr,Nr,Nn[N.NODE]),Y[N.NODE]=!1),(Y[N.DRAG]||Nn[N.DRAG])&&(pa(Si,ys,Nn[N.DRAG]),Y[N.DRAG]=!1)}N.prevViewport=Ye,N.clearingMotionBlur&&(N.clearingMotionBlur=!1,N.motionBlurCleared=!0,N.motionBlur=!0),ce&&(N.motionBlurTimeout=setTimeout(function(){N.motionBlurTimeout=null,N.clearedForMotionBlur[N.NODE]=!1,N.clearedForMotionBlur[N.DRAG]=!1,N.motionBlur=!1,N.clearingMotionBlur=!Z,N.mbFrames=0,Y[N.NODE]=!0,Y[N.DRAG]=!0,N.redraw()},xie)),m||H.emit("render")};var iy={};iy.drawPolygonPath=function(x,m,k,S,M,O){var N=S/2,$=M/2;x.beginPath&&x.beginPath(),x.moveTo(m+N*O[0],k+$*O[1]);for(var H=1;H0&&N>0){ve.clearRect(0,0,O,N),ve.globalCompositeOperation="source-over";var me=this.getCachedZSortedEles();if(x.full)ve.translate(-S.x1*q,-S.y1*q),ve.scale(q,q),this.drawElements(ve,me),ve.scale(1/q,1/q),ve.translate(S.x1*q,S.y1*q);else{var Le=m.pan(),_e={x:Le.x*q,y:Le.y*q};q*=m.zoom(),ve.translate(_e.x,_e.y),ve.scale(q,q),this.drawElements(ve,me),ve.scale(1/q,1/q),ve.translate(-_e.x,-_e.y)}x.bg&&(ve.globalCompositeOperation="destination-over",ve.fillStyle=x.bg,ve.rect(0,0,O,N),ve.fill())}return ce};function kie(x,m){for(var k=atob(x),S=new ArrayBuffer(k.length),M=new Uint8Array(S),O=0;O"u"?"undefined":u(OffscreenCanvas))!=="undefined"?k=new OffscreenCanvas(x,m):(k=document.createElement("canvas"),k.width=x,k.height=m),k},[pz,Q2,J2,bk,y5,w8,qg,iy,mk,Cz].forEach(function(x){yt(jc,x)});var $p=[{name:"null",impl:W$},{name:"base",impl:az},{name:"canvas",impl:Sz}],Eie=[{type:"layout",extensions:qre},{type:"renderer",extensions:$p}],Tie={},Cie={};function Sie(x,m,k){var S=k,M=function(mt){hu("Can not register `"+m+"` for `"+x+"` since `"+mt+"` already exists in the prototype and can not be overridden")};if(x==="core"){if(lk.prototype[m])return M(m);lk.prototype[m]=k}else if(x==="collection"){if(V0.prototype[m])return M(m);V0.prototype[m]=k}else if(x==="layout"){for(var O=function(mt){this.options=mt,k.call(this,mt),se(this._private)||(this._private={}),this._private.cy=mt.cy,this._private.listeners=[],this.createEmitter()},N=O.prototype=Object.create(k.prototype),$=[],H=0;H<$.length;H++){var q=$[H];N[q]=N[q]||function(){return this}}N.start&&!N.run?N.run=function(){return this.start(),this}:!N.start&&N.run&&(N.start=function(){return this.run(),this});var Y=k.prototype.stop;N.stop=function(){var Ye=this.options;if(Ye&&Ye.animate){var mt=this.animations;if(mt)for(var Je=0;Jej&&(this.rect.x-=(this.labelWidth-j)/2,this.setWidth(this.labelWidth)),this.labelHeight>K&&(this.labelPos=="center"?this.rect.y-=(this.labelHeight-K)/2:this.labelPos=="top"&&(this.rect.y-=this.labelHeight-K),this.setHeight(this.labelHeight))}}},P.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==b.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},P.prototype.transform=function(F){var j=this.rect.x;j>T.WORLD_BOUNDARY?j=T.WORLD_BOUNDARY:j<-T.WORLD_BOUNDARY&&(j=-T.WORLD_BOUNDARY);var K=this.rect.y;K>T.WORLD_BOUNDARY?K=T.WORLD_BOUNDARY:K<-T.WORLD_BOUNDARY&&(K=-T.WORLD_BOUNDARY);var ee=new A(j,K),ie=F.inverseTransformPoint(ee);this.setLocation(ie.x,ie.y)},P.prototype.getLeft=function(){return this.rect.x},P.prototype.getRight=function(){return this.rect.x+this.rect.width},P.prototype.getTop=function(){return this.rect.y},P.prototype.getBottom=function(){return this.rect.y+this.rect.height},P.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},u.exports=P},function(u,d,p){function v(b,y){b==null&&y==null?(this.x=0,this.y=0):(this.x=b,this.y=y)}v.prototype.getX=function(){return this.x},v.prototype.getY=function(){return this.y},v.prototype.setX=function(b){this.x=b},v.prototype.setY=function(b){this.y=b},v.prototype.getDifference=function(b){return new DimensionD(this.x-b.x,this.y-b.y)},v.prototype.getCopy=function(){return new v(this.x,this.y)},v.prototype.translate=function(b){return this.x+=b.width,this.y+=b.height,this},u.exports=v},function(u,d,p){var v=p(2),b=p(10),y=p(0),T=p(6),_=p(3),A=p(1),P=p(13),R=p(12),F=p(11);function j(ee,ie,oe){v.call(this,oe),this.estimatedSize=b.MIN_VALUE,this.margin=y.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=ee,ie!=null&&ie instanceof T?this.graphManager=ie:ie!=null&&ie instanceof Layout&&(this.graphManager=ie.graphManager)}j.prototype=Object.create(v.prototype);for(var K in v)j[K]=v[K];j.prototype.getNodes=function(){return this.nodes},j.prototype.getEdges=function(){return this.edges},j.prototype.getGraphManager=function(){return this.graphManager},j.prototype.getParent=function(){return this.parent},j.prototype.getLeft=function(){return this.left},j.prototype.getRight=function(){return this.right},j.prototype.getTop=function(){return this.top},j.prototype.getBottom=function(){return this.bottom},j.prototype.isConnected=function(){return this.isConnected},j.prototype.add=function(ee,ie,oe){if(ie==null&&oe==null){var pe=ee;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(pe)>-1)throw"Node already in graph!";return pe.owner=this,this.getNodes().push(pe),pe}else{var be=ee;if(!(this.getNodes().indexOf(ie)>-1&&this.getNodes().indexOf(oe)>-1))throw"Source or target not in graph!";if(!(ie.owner==oe.owner&&ie.owner==this))throw"Both owners must be this graph!";return ie.owner!=oe.owner?null:(be.source=ie,be.target=oe,be.isInterGraph=!1,this.getEdges().push(be),ie.edges.push(be),oe!=ie&&oe.edges.push(be),be)}},j.prototype.remove=function(ee){var ie=ee;if(ee instanceof _){if(ie==null)throw"Node is null!";if(!(ie.owner!=null&&ie.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var oe=ie.edges.slice(),pe,be=oe.length,ae=0;ae-1&&de>-1))throw"Source and/or target doesn't know this edge!";pe.source.edges.splice(se,1),pe.target!=pe.source&&pe.target.edges.splice(de,1);var ne=pe.source.owner.getEdges().indexOf(pe);if(ne==-1)throw"Not in owner's edge list!";pe.source.owner.getEdges().splice(ne,1)}},j.prototype.updateLeftTop=function(){for(var ee=b.MAX_VALUE,ie=b.MAX_VALUE,oe,pe,be,ae=this.getNodes(),ne=ae.length,se=0;seoe&&(ee=oe),ie>pe&&(ie=pe)}return ee==b.MAX_VALUE?null:(ae[0].getParent().paddingLeft!=null?be=ae[0].getParent().paddingLeft:be=this.margin,this.left=ie-be,this.top=ee-be,new R(this.left,this.top))},j.prototype.updateBounds=function(ee){for(var ie=b.MAX_VALUE,oe=-b.MAX_VALUE,pe=b.MAX_VALUE,be=-b.MAX_VALUE,ae,ne,se,de,X,ge=this.nodes,W=ge.length,xe=0;xeae&&(ie=ae),oese&&(pe=se),beae&&(ie=ae),oese&&(pe=se),be=this.nodes.length){var W=0;oe.forEach(function(xe){xe.owner==ee&&W++}),W==this.nodes.length&&(this.isConnected=!0)}},u.exports=j},function(u,d,p){var v,b=p(1);function y(T){v=p(5),this.layout=T,this.graphs=[],this.edges=[]}y.prototype.addRoot=function(){var T=this.layout.newGraph(),_=this.layout.newNode(null),A=this.add(T,_);return this.setRootGraph(A),this.rootGraph},y.prototype.add=function(T,_,A,P,R){if(A==null&&P==null&&R==null){if(T==null)throw"Graph is null!";if(_==null)throw"Parent node is null!";if(this.graphs.indexOf(T)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(T),T.parent!=null)throw"Already has a parent!";if(_.child!=null)throw"Already has a child!";return T.parent=_,_.child=T,T}else{R=A,P=_,A=T;var F=P.getOwner(),j=R.getOwner();if(!(F!=null&&F.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(j!=null&&j.getGraphManager()==this))throw"Target not in this graph mgr!";if(F==j)return A.isInterGraph=!1,F.add(A,P,R);if(A.isInterGraph=!0,A.source=P,A.target=R,this.edges.indexOf(A)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(A),!(A.source!=null&&A.target!=null))throw"Edge source and/or target is null!";if(!(A.source.edges.indexOf(A)==-1&&A.target.edges.indexOf(A)==-1))throw"Edge already in source and/or target incidency list!";return A.source.edges.push(A),A.target.edges.push(A),A}},y.prototype.remove=function(T){if(T instanceof v){var _=T;if(_.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(_==this.rootGraph||_.parent!=null&&_.parent.graphManager==this))throw"Invalid parent node!";var A=[];A=A.concat(_.getEdges());for(var P,R=A.length,F=0;F=T.getRight()?_[0]+=Math.min(T.getX()-y.getX(),y.getRight()-T.getRight()):T.getX()<=y.getX()&&T.getRight()>=y.getRight()&&(_[0]+=Math.min(y.getX()-T.getX(),T.getRight()-y.getRight())),y.getY()<=T.getY()&&y.getBottom()>=T.getBottom()?_[1]+=Math.min(T.getY()-y.getY(),y.getBottom()-T.getBottom()):T.getY()<=y.getY()&&T.getBottom()>=y.getBottom()&&(_[1]+=Math.min(y.getY()-T.getY(),T.getBottom()-y.getBottom()));var R=Math.abs((T.getCenterY()-y.getCenterY())/(T.getCenterX()-y.getCenterX()));T.getCenterY()===y.getCenterY()&&T.getCenterX()===y.getCenterX()&&(R=1);var F=R*_[0],j=_[1]/R;_[0]F)return _[0]=A,_[1]=K,_[2]=R,_[3]=ge,!1;if(PR)return _[0]=j,_[1]=P,_[2]=de,_[3]=F,!1;if(AR?(_[0]=ie,_[1]=oe,Fe=!0):(_[0]=ee,_[1]=K,Fe=!0):je===Se&&(A>R?(_[0]=j,_[1]=K,Fe=!0):(_[0]=pe,_[1]=oe,Fe=!0)),-Ie===Se?R>A?(_[2]=X,_[3]=ge,Pe=!0):(_[2]=de,_[3]=se,Pe=!0):Ie===Se&&(R>A?(_[2]=ne,_[3]=se,Pe=!0):(_[2]=W,_[3]=ge,Pe=!0)),Fe&&Pe)return!1;if(A>R?P>F?(Ce=this.getCardinalDirection(je,Se,4),ke=this.getCardinalDirection(Ie,Se,2)):(Ce=this.getCardinalDirection(-je,Se,3),ke=this.getCardinalDirection(-Ie,Se,1)):P>F?(Ce=this.getCardinalDirection(-je,Se,1),ke=this.getCardinalDirection(-Ie,Se,3)):(Ce=this.getCardinalDirection(je,Se,2),ke=this.getCardinalDirection(Ie,Se,4)),!Fe)switch(Ce){case 1:Ft=K,Ke=A+-ae/Se,_[0]=Ke,_[1]=Ft;break;case 2:Ke=pe,Ft=P+be*Se,_[0]=Ke,_[1]=Ft;break;case 3:Ft=oe,Ke=A+ae/Se,_[0]=Ke,_[1]=Ft;break;case 4:Ke=ie,Ft=P+-be*Se,_[0]=Ke,_[1]=Ft;break}if(!Pe)switch(ke){case 1:gn=se,Ne=R+-U/Se,_[2]=Ne,_[3]=gn;break;case 2:Ne=W,gn=F+xe*Se,_[2]=Ne,_[3]=gn;break;case 3:gn=ge,Ne=R+U/Se,_[2]=Ne,_[3]=gn;break;case 4:Ne=X,gn=F+-xe*Se,_[2]=Ne,_[3]=gn;break}}return!1},b.getCardinalDirection=function(y,T,_){return y>T?_:1+_%4},b.getIntersection=function(y,T,_,A){if(A==null)return this.getIntersection2(y,T,_);var P=y.x,R=y.y,F=T.x,j=T.y,K=_.x,ee=_.y,ie=A.x,oe=A.y,pe=void 0,be=void 0,ae=void 0,ne=void 0,se=void 0,de=void 0,X=void 0,ge=void 0,W=void 0;return ae=j-R,se=P-F,X=F*R-P*j,ne=oe-ee,de=K-ie,ge=ie*ee-K*oe,W=ae*de-ne*se,W===0?null:(pe=(se*ge-de*X)/W,be=(ne*X-ae*ge)/W,new v(pe,be))},b.angleOfVector=function(y,T,_,A){var P=void 0;return y!==_?(P=Math.atan((A-T)/(_-y)),_0?1:b<0?-1:0},v.floor=function(b){return b<0?Math.ceil(b):Math.floor(b)},v.ceil=function(b){return b<0?Math.floor(b):Math.ceil(b)},u.exports=v},function(u,d,p){function v(){}v.MAX_VALUE=2147483647,v.MIN_VALUE=-2147483648,u.exports=v},function(u,d,p){var v=function(){function P(R,F){for(var j=0;j"u"?"undefined":v(y);return y==null||T!="object"&&T!="function"},u.exports=b},function(u,d,p){function v(K){if(Array.isArray(K)){for(var ee=0,ie=Array(K.length);ee0&ⅇ){for(ae.push(se[0]);ae.length>0&ⅇ){var de=ae[0];ae.splice(0,1),be.add(de);for(var X=de.getEdges(),pe=0;pe-1&&se.splice(U,1)}be=new Set,ne=new Map}}return K},j.prototype.createDummyNodesForBendpoints=function(K){for(var ee=[],ie=K.source,oe=this.graphManager.calcLowestCommonAncestor(K.source,K.target),pe=0;pe0){for(var oe=this.edgeToDummyNodes.get(ie),pe=0;pe=0&&ee.splice(ge,1);var W=ne.getNeighborsList();W.forEach(function(Fe){if(ie.indexOf(Fe)<0){var Pe=oe.get(Fe),je=Pe-1;je==1&&de.push(Fe),oe.set(Fe,je)}})}ie=ie.concat(de),(ee.length==1||ee.length==2)&&(pe=!0,be=ee[0])}return be},j.prototype.setGraphManager=function(K){this.graphManager=K},u.exports=j},function(u,d,p){function v(){}v.seed=1,v.x=0,v.nextDouble=function(){return v.x=Math.sin(v.seed++)*1e4,v.x-Math.floor(v.x)},u.exports=v},function(u,d,p){var v=p(4);function b(y,T){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}b.prototype.getWorldOrgX=function(){return this.lworldOrgX},b.prototype.setWorldOrgX=function(y){this.lworldOrgX=y},b.prototype.getWorldOrgY=function(){return this.lworldOrgY},b.prototype.setWorldOrgY=function(y){this.lworldOrgY=y},b.prototype.getWorldExtX=function(){return this.lworldExtX},b.prototype.setWorldExtX=function(y){this.lworldExtX=y},b.prototype.getWorldExtY=function(){return this.lworldExtY},b.prototype.setWorldExtY=function(y){this.lworldExtY=y},b.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},b.prototype.setDeviceOrgX=function(y){this.ldeviceOrgX=y},b.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},b.prototype.setDeviceOrgY=function(y){this.ldeviceOrgY=y},b.prototype.getDeviceExtX=function(){return this.ldeviceExtX},b.prototype.setDeviceExtX=function(y){this.ldeviceExtX=y},b.prototype.getDeviceExtY=function(){return this.ldeviceExtY},b.prototype.setDeviceExtY=function(y){this.ldeviceExtY=y},b.prototype.transformX=function(y){var T=0,_=this.lworldExtX;return _!=0&&(T=this.ldeviceOrgX+(y-this.lworldOrgX)*this.ldeviceExtX/_),T},b.prototype.transformY=function(y){var T=0,_=this.lworldExtY;return _!=0&&(T=this.ldeviceOrgY+(y-this.lworldOrgY)*this.ldeviceExtY/_),T},b.prototype.inverseTransformX=function(y){var T=0,_=this.ldeviceExtX;return _!=0&&(T=this.lworldOrgX+(y-this.ldeviceOrgX)*this.lworldExtX/_),T},b.prototype.inverseTransformY=function(y){var T=0,_=this.ldeviceExtY;return _!=0&&(T=this.lworldOrgY+(y-this.ldeviceOrgY)*this.lworldExtY/_),T},b.prototype.inverseTransformPoint=function(y){var T=new v(this.inverseTransformX(y.x),this.inverseTransformY(y.y));return T},u.exports=b},function(u,d,p){function v(F){if(Array.isArray(F)){for(var j=0,K=Array(F.length);jy.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*y.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(F-y.ADAPTATION_LOWER_NODE_LIMIT)/(y.ADAPTATION_UPPER_NODE_LIMIT-y.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-y.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=y.MAX_NODE_DISPLACEMENT_INCREMENTAL):(F>y.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(y.COOLING_ADAPTATION_FACTOR,1-(F-y.ADAPTATION_LOWER_NODE_LIMIT)/(y.ADAPTATION_UPPER_NODE_LIMIT-y.ADAPTATION_LOWER_NODE_LIMIT)*(1-y.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=y.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},P.prototype.calcSpringForces=function(){for(var F=this.getAllEdges(),j,K=0;K0&&arguments[0]!==void 0?arguments[0]:!0,j=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,K,ee,ie,oe,pe=this.getAllNodes(),be;if(this.useFRGridVariant)for(this.totalIterations%y.GRID_CALCULATION_CHECK_PERIOD==1&&F&&this.updateGrid(),be=new Set,K=0;Kae||be>ae)&&(F.gravitationForceX=-this.gravityConstant*ie,F.gravitationForceY=-this.gravityConstant*oe)):(ae=j.getEstimatedSize()*this.compoundGravityRangeFactor,(pe>ae||be>ae)&&(F.gravitationForceX=-this.gravityConstant*ie*this.compoundGravityConstant,F.gravitationForceY=-this.gravityConstant*oe*this.compoundGravityConstant))},P.prototype.isConverged=function(){var F,j=!1;return this.totalIterations>this.maxIterations/3&&(j=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),F=this.totalDisplacement=pe.length||ae>=pe[0].length)){for(var ne=0;neP}}]),_}();u.exports=T},function(u,d,p){var v=function(){function T(_,A){for(var P=0;P2&&arguments[2]!==void 0?arguments[2]:1,R=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,F=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;b(this,T),this.sequence1=_,this.sequence2=A,this.match_score=P,this.mismatch_penalty=R,this.gap_penalty=F,this.iMax=_.length+1,this.jMax=A.length+1,this.grid=new Array(this.iMax);for(var j=0;j=0;_--){var A=this.listeners[_];A.event===y&&A.callback===T&&this.listeners.splice(_,1)}},b.emit=function(y,T){for(var _=0;_A.coolingFactor*A.maxNodeDisplacement&&(this.displacementX=A.coolingFactor*A.maxNodeDisplacement*y.sign(this.displacementX)),Math.abs(this.displacementY)>A.coolingFactor*A.maxNodeDisplacement&&(this.displacementY=A.coolingFactor*A.maxNodeDisplacement*y.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),A.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},T.prototype.propogateDisplacementToChildren=function(A,P){for(var R=this.getChild().getNodes(),F,j=0;j0)this.positionNodesRadially(se);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var de=new Set(this.getAllNodes()),X=this.nodesWithGravity.filter(function(ge){return de.has(ge)});this.graphManager.setAllNodesToApplyGravitation(X),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},ae.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%R.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 se=new Set(this.getAllNodes()),de=this.nodesWithGravity.filter(function(W){return se.has(W)});this.graphManager.setAllNodesToApplyGravitation(de),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=R.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=R.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var X=!this.isTreeGrowing&&!this.isGrowthFinished,ge=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(X,ge),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},ae.prototype.getPositionsData=function(){for(var se=this.graphManager.getAllNodes(),de={},X=0;X1){var Fe;for(Fe=0;Fege&&(ge=Math.floor(U.y)),xe=Math.floor(U.x+P.DEFAULT_COMPONENT_SEPERATION)}this.transform(new K(F.WORLD_CENTER_X-U.x/2,F.WORLD_CENTER_Y-U.y/2))},ae.radialLayout=function(se,de,X){var ge=Math.max(this.maxDiagonalInTree(se),P.DEFAULT_RADIAL_SEPARATION);ae.branchRadialLayout(de,null,0,359,0,ge);var W=pe.calculateBounds(se),xe=new be;xe.setDeviceOrgX(W.getMinX()),xe.setDeviceOrgY(W.getMinY()),xe.setWorldOrgX(X.x),xe.setWorldOrgY(X.y);for(var U=0;U1;){var gn=Ne[0];Ne.splice(0,1);var _t=Se.indexOf(gn);_t>=0&&Se.splice(_t,1),Ke--,Ce--}de!=null?Ft=(Se.indexOf(Ne[0])+1)%Ke:Ft=0;for(var Et=Math.abs(ge-X)/Ce,Gt=Ft;ke!=Ce;Gt=++Gt%Ke){var ln=Se[Gt].getOtherEnd(se);if(ln!=de){var xt=(X+ke*Et)%360,Pt=(xt+Et)%360;ae.branchRadialLayout(ln,se,xt,Pt,W+xe,xe),ke++}}},ae.maxDiagonalInTree=function(se){for(var de=ie.MIN_VALUE,X=0;Xde&&(de=W)}return de},ae.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},ae.prototype.groupZeroDegreeMembers=function(){var se=this,de={};this.memberGroups={},this.idToDummyNode={};for(var X=[],ge=this.graphManager.getAllNodes(),W=0;W"u"&&(de[Fe]=[]),de[Fe]=de[Fe].concat(xe)}Object.keys(de).forEach(function(Pe){if(de[Pe].length>1){var je="DummyCompound_"+Pe;se.memberGroups[je]=de[Pe];var Ie=de[Pe][0].getParent(),Se=new _(se.graphManager);Se.id=je,Se.paddingLeft=Ie.paddingLeft||0,Se.paddingRight=Ie.paddingRight||0,Se.paddingBottom=Ie.paddingBottom||0,Se.paddingTop=Ie.paddingTop||0,se.idToDummyNode[je]=Se;var Ce=se.getGraphManager().add(se.newGraph(),Se),ke=Ie.getChild();ke.add(Se);for(var Ke=0;Ke=0;se--){var de=this.compoundOrder[se],X=de.id,ge=de.paddingLeft,W=de.paddingTop;this.adjustLocations(this.tiledMemberPack[X],de.rect.x,de.rect.y,ge,W)}},ae.prototype.repopulateZeroDegreeMembers=function(){var se=this,de=this.tiledZeroDegreePack;Object.keys(de).forEach(function(X){var ge=se.idToDummyNode[X],W=ge.paddingLeft,xe=ge.paddingTop;se.adjustLocations(de[X],ge.rect.x,ge.rect.y,W,xe)})},ae.prototype.getToBeTiled=function(se){var de=se.id;if(this.toBeTiled[de]!=null)return this.toBeTiled[de];var X=se.getChild();if(X==null)return this.toBeTiled[de]=!1,!1;for(var ge=X.getNodes(),W=0;W0)return this.toBeTiled[de]=!1,!1;if(xe.getChild()==null){this.toBeTiled[xe.id]=!1;continue}if(!this.getToBeTiled(xe))return this.toBeTiled[de]=!1,!1}return this.toBeTiled[de]=!0,!0},ae.prototype.getNodeDegree=function(se){se.id;for(var de=se.getEdges(),X=0,ge=0;gePe&&(Pe=Ie.rect.height)}X+=Pe+se.verticalPadding}},ae.prototype.tileCompoundMembers=function(se,de){var X=this;this.tiledMemberPack=[],Object.keys(se).forEach(function(ge){var W=de[ge];X.tiledMemberPack[ge]=X.tileNodes(se[ge],W.paddingLeft+W.paddingRight),W.rect.width=X.tiledMemberPack[ge].width,W.rect.height=X.tiledMemberPack[ge].height})},ae.prototype.tileNodes=function(se,de){var X=P.TILING_PADDING_VERTICAL,ge=P.TILING_PADDING_HORIZONTAL,W={rows:[],rowWidth:[],rowHeight:[],width:0,height:de,verticalPadding:X,horizontalPadding:ge};se.sort(function(Fe,Pe){return Fe.rect.width*Fe.rect.height>Pe.rect.width*Pe.rect.height?-1:Fe.rect.width*Fe.rect.height0&&(U+=se.horizontalPadding),se.rowWidth[X]=U,se.width0&&(Fe+=se.verticalPadding);var Pe=0;Fe>se.rowHeight[X]&&(Pe=se.rowHeight[X],se.rowHeight[X]=Fe,Pe=se.rowHeight[X]-Pe),se.height+=Pe,se.rows[X].push(de)},ae.prototype.getShortestRowIndex=function(se){for(var de=-1,X=Number.MAX_VALUE,ge=0;geX&&(de=ge,X=se.rowWidth[ge]);return de},ae.prototype.canAddHorizontal=function(se,de,X){var ge=this.getShortestRowIndex(se);if(ge<0)return!0;var W=se.rowWidth[ge];if(W+se.horizontalPadding+de<=se.width)return!0;var xe=0;se.rowHeight[ge]0&&(xe=X+se.verticalPadding-se.rowHeight[ge]);var U;se.width-W>=de+se.horizontalPadding?U=(se.height+xe)/(W+de+se.horizontalPadding):U=(se.height+xe)/se.width,xe=X+se.verticalPadding;var Fe;return se.widthxe&&de!=X){ge.splice(-1,1),se.rows[X].push(W),se.rowWidth[de]=se.rowWidth[de]-xe,se.rowWidth[X]=se.rowWidth[X]+xe,se.width=se.rowWidth[instance.getLongestRowIndex(se)];for(var U=Number.MIN_VALUE,Fe=0;FeU&&(U=ge[Fe].height);de>0&&(U+=se.verticalPadding);var Pe=se.rowHeight[de]+se.rowHeight[X];se.rowHeight[de]=U,se.rowHeight[X]0)for(var ke=W;ke<=xe;ke++)Ce[0]+=this.grid[ke][U-1].length+this.grid[ke][U].length-1;if(xe0)for(var ke=U;ke<=Fe;ke++)Ce[3]+=this.grid[W-1][ke].length+this.grid[W][ke].length-1;for(var Ke=ie.MAX_VALUE,Ft,Ne,gn=0;gn0){var Fe;Fe=be.getGraphManager().add(be.newGraph(),X),this.processChildrenList(Fe,de,be)}}},K.prototype.stop=function(){return this.stopped=!0,this};var ie=function(pe){pe("layout","cose-bilkent",K)};typeof cytoscape<"u"&&ie(cytoscape),d.exports=ie}])})})(dWe);var gon=dWe.exports;const pon=hC(gon),bon=12,mon=function(i,s,u,d){s.append("path").attr("id","node-"+u.id).attr("class","node-bkg node-"+i.type2Str(u.type)).attr("d",`M0 ${u.height-5} v${-u.height+2*5} q0,-5 5,-5 h${u.width-2*5} q5,0 5,5 v${u.height-5} H0 Z`),s.append("line").attr("class","node-line-"+d).attr("x1",0).attr("y1",u.height).attr("x2",u.width).attr("y2",u.height)},von=function(i,s,u){s.append("rect").attr("id","node-"+u.id).attr("class","node-bkg node-"+i.type2Str(u.type)).attr("height",u.height).attr("width",u.width)},won=function(i,s,u){const d=u.width,p=u.height,v=.15*d,b=.25*d,y=.35*d,T=.2*d;s.append("path").attr("id","node-"+u.id).attr("class","node-bkg node-"+i.type2Str(u.type)).attr("d",`M0 0 a${v},${v} 0 0,1 ${d*.25},${-1*d*.1} + a${y},${y} 1 0,1 ${d*.4},${-1*d*.1} + a${b},${b} 1 0,1 ${d*.35},${1*d*.2} + + a${v},${v} 1 0,1 ${d*.15},${1*p*.35} + a${T},${T} 1 0,1 ${-1*d*.15},${1*p*.65} + + a${b},${v} 1 0,1 ${-1*d*.25},${d*.15} + a${y},${y} 1 0,1 ${-1*d*.5},0 + a${v},${v} 1 0,1 ${-1*d*.25},${-1*d*.15} + + a${v},${v} 1 0,1 ${-1*d*.1},${-1*p*.35} + a${T},${T} 1 0,1 ${d*.1},${-1*p*.65} + + H0 V0 Z`)},yon=function(i,s,u){const d=u.width,p=u.height,v=.15*d;s.append("path").attr("id","node-"+u.id).attr("class","node-bkg node-"+i.type2Str(u.type)).attr("d",`M0 0 a${v},${v} 1 0,0 ${d*.25},${-1*p*.1} + a${v},${v} 1 0,0 ${d*.25},0 + a${v},${v} 1 0,0 ${d*.25},0 + a${v},${v} 1 0,0 ${d*.25},${1*p*.1} + + a${v},${v} 1 0,0 ${d*.15},${1*p*.33} + a${v*.8},${v*.8} 1 0,0 0,${1*p*.34} + a${v},${v} 1 0,0 ${-1*d*.15},${1*p*.33} + + a${v},${v} 1 0,0 ${-1*d*.25},${p*.15} + a${v},${v} 1 0,0 ${-1*d*.25},0 + a${v},${v} 1 0,0 ${-1*d*.25},0 + a${v},${v} 1 0,0 ${-1*d*.25},${-1*p*.15} + + a${v},${v} 1 0,0 ${-1*d*.1},${-1*p*.33} + a${v*.8},${v*.8} 1 0,0 0,${-1*p*.34} + a${v},${v} 1 0,0 ${d*.1},${-1*p*.33} + + H0 V0 Z`)},xon=function(i,s,u){s.append("circle").attr("id","node-"+u.id).attr("class","node-bkg node-"+i.type2Str(u.type)).attr("r",u.width/2)};function kon(i,s,u,d,p){return i.insert("polygon",":first-child").attr("points",d.map(function(v){return v.x+","+v.y}).join(" ")).attr("transform","translate("+(p.width-s)/2+", "+u+")")}const Eon=function(i,s,u){const d=u.height,v=d/4,b=u.width-u.padding+2*v,y=[{x:v,y:0},{x:b-v,y:0},{x:b,y:-d/2},{x:b-v,y:-d},{x:v,y:-d},{x:0,y:-d/2}];kon(s,b,d,y,u)},Ton=function(i,s,u){s.append("rect").attr("id","node-"+u.id).attr("class","node-bkg node-"+i.type2Str(u.type)).attr("height",u.height).attr("rx",u.padding).attr("ry",u.padding).attr("width",u.width)},Con=function(i,s,u,d,p){const v=p.htmlLabels,b=d%(bon-1),y=s.append("g");u.section=b;let T="section-"+b;b<0&&(T+=" section-root"),y.attr("class",(u.class?u.class+" ":"")+"mindmap-node "+T);const _=y.append("g"),A=y.append("g"),P=u.descr.replace(/()/g,` +`);JQ(A,P,{useHtmlLabels:v,width:u.width,classes:"mindmap-node-label"}),v||A.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");const R=A.node().getBBox(),[F]=NC(p.fontSize);if(u.height=R.height+F*1.1*.5+u.padding,u.width=R.width+2*u.padding,u.icon)if(u.type===i.nodeType.CIRCLE)u.height+=50,u.width+=50,y.append("foreignObject").attr("height","50px").attr("width",u.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+b+" "+u.icon),A.attr("transform","translate("+u.width/2+", "+(u.height/2-1.5*u.padding)+")");else{u.width+=50;const j=u.height;u.height=Math.max(j,60);const K=Math.abs(u.height-j);y.append("foreignObject").attr("width","60px").attr("height",u.height).attr("style","text-align: center;margin-top:"+K/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+b+" "+u.icon),A.attr("transform","translate("+(25+u.width/2)+", "+(K/2+u.padding/2)+")")}else if(v){const j=(u.width-R.width)/2,K=(u.height-R.height)/2;A.attr("transform","translate("+j+", "+K+")")}else{const j=u.width/2,K=u.padding/2;A.attr("transform","translate("+j+", "+K+")")}switch(u.type){case i.nodeType.DEFAULT:mon(i,_,u,b);break;case i.nodeType.ROUNDED_RECT:Ton(i,_,u);break;case i.nodeType.RECT:von(i,_,u);break;case i.nodeType.CIRCLE:_.attr("transform","translate("+u.width/2+", "+ +u.height/2+")"),xon(i,_,u);break;case i.nodeType.CLOUD:won(i,_,u);break;case i.nodeType.BANG:yon(i,_,u);break;case i.nodeType.HEXAGON:Eon(i,_,u);break}return i.setElementForId(u.id,y),u.height},Son=function(i,s){const u=i.getElementById(s.id),d=s.x||0,p=s.y||0;u.attr("transform","translate("+d+","+p+")")};fWe.use(pon);function bWe(i,s,u,d,p){Con(i,s,u,d,p),u.children&&u.children.forEach((v,b)=>{bWe(i,s,v,d<0?b:d,p)})}function _on(i,s){s.edges().map((u,d)=>{const p=u.data();if(u[0]._private.bodyBounds){const v=u[0]._private.rscratch;Xe.trace("Edge: ",d,p),i.insert("path").attr("d",`M ${v.startX},${v.startY} L ${v.midX},${v.midY} L${v.endX},${v.endY} `).attr("class","edge section-edge-"+p.section+" edge-depth-"+p.depth)}})}function mWe(i,s,u,d){s.add({group:"nodes",data:{id:i.id.toString(),labelText:i.descr,height:i.height,width:i.width,level:d,nodeId:i.id,padding:i.padding,type:i.type},position:{x:i.x,y:i.y}}),i.children&&i.children.forEach(p=>{mWe(p,s,u,d+1),s.add({group:"edges",data:{id:`${i.id}_${p.id}`,source:i.id,target:p.id,depth:d,section:p.section}})})}function Aon(i,s){return new Promise(u=>{const d=Ir("body").append("div").attr("id","cy").attr("style","display:none"),p=fWe({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});d.remove(),mWe(i,p,s,0),p.nodes().forEach(function(v){v.layoutDimensions=()=>{const b=v.data();return{w:b.width,h:b.height}}}),p.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),p.ready(v=>{Xe.info("Ready",v),u(p)})})}function Lon(i,s){s.nodes().map((u,d)=>{const p=u.data();p.x=u.position().x,p.y=u.position().y,Son(i,p);const v=i.getElementById(p.nodeId);Xe.info("Id:",d,"Position: (",u.position().x,", ",u.position().y,")",p),v.attr("transform",`translate(${u.position().x-p.width/2}, ${u.position().y-p.height/2})`),v.attr("attr",`apa-${d})`)})}const Mon={draw:async(i,s,u,d)=>{var P,R;Xe.debug(`Rendering mindmap diagram +`+i);const p=d.db,v=p.getMindmap();if(!v)return;const b=qt();b.htmlLabels=!1;const y=rR(s),T=y.append("g");T.attr("class","mindmap-edges");const _=y.append("g");_.attr("class","mindmap-nodes"),bWe(p,_,v,-1,b);const A=await Aon(v,b);_on(T,A),Lon(p,A),y9(void 0,y,((P=b.mindmap)==null?void 0:P.padding)??sh.mindmap.padding,((R=b.mindmap)==null?void 0:R.useMaxWidth)??sh.mindmap.useMaxWidth)}},Don=i=>{let s="";for(let u=0;u` + .edge { + stroke-width: 3; + } + ${Don(i)} + .section-root rect, .section-root path, .section-root circle, .section-root polygon { + fill: ${i.git0}; + } + .section-root text { + fill: ${i.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; + } +`}},Symbol.toStringTag,{value:"Module"}));var iwe=function(){var i=function(y,T,_,A){for(_=_||{},A=y.length;A--;_[y[A]]=T);return _},s=[1,9],u=[1,10],d=[1,5,10,12],p={trace:function(){},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:function(T,_,A,P,R,F,j){var K=F.length-1;switch(R){case 7:const ee=P.findOrCreateNode(F[K-4].trim().replaceAll('""','"')),ie=P.findOrCreateNode(F[K-2].trim().replaceAll('""','"')),oe=parseFloat(F[K].trim());P.addLink(ee,ie,oe);break;case 8:case 9:case 11:this.$=F[K];break;case 10:this.$=F[K-1];break}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:s,20:u},{1:[2,6],7:11,10:[1,12]},i(u,[2,4],{9:13,5:[1,14]}),{12:[1,15]},i(d,[2,8]),i(d,[2,9]),{19:[1,16]},i(d,[2,11]),{1:[2,1]},{1:[2,5]},i(u,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:s,20:u},{15:18,16:7,17:8,18:s,20:u},{18:[1,19]},i(u,[2,3]),{12:[1,20]},i(d,[2,10]),{15:21,16:7,17:8,18:s,20:u},i([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:function(T,_){if(_.recoverable)this.trace(T);else{var A=new Error(T);throw A.hash=_,A}},parse:function(T){var _=this,A=[0],P=[],R=[null],F=[],j=this.table,K="",ee=0,ie=0,oe=2,pe=1,be=F.slice.call(arguments,1),ae=Object.create(this.lexer),ne={yy:{}};for(var se in this.yy)Object.prototype.hasOwnProperty.call(this.yy,se)&&(ne.yy[se]=this.yy[se]);ae.setInput(T,ne.yy),ne.yy.lexer=ae,ne.yy.parser=this,typeof ae.yylloc>"u"&&(ae.yylloc={});var de=ae.yylloc;F.push(de);var X=ae.options&&ae.options.ranges;typeof ne.yy.parseError=="function"?this.parseError=ne.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ge(){var Ke;return Ke=P.pop()||ae.lex()||pe,typeof Ke!="number"&&(Ke instanceof Array&&(P=Ke,Ke=P.pop()),Ke=_.symbols_[Ke]||Ke),Ke}for(var W,xe,U,Fe,Pe={},je,Ie,Se,Ce;;){if(xe=A[A.length-1],this.defaultActions[xe]?U=this.defaultActions[xe]:((W===null||typeof W>"u")&&(W=ge()),U=j[xe]&&j[xe][W]),typeof U>"u"||!U.length||!U[0]){var ke="";Ce=[];for(je in j[xe])this.terminals_[je]&&je>oe&&Ce.push("'"+this.terminals_[je]+"'");ae.showPosition?ke="Parse error on line "+(ee+1)+`: +`+ae.showPosition()+` +Expecting `+Ce.join(", ")+", got '"+(this.terminals_[W]||W)+"'":ke="Parse error on line "+(ee+1)+": Unexpected "+(W==pe?"end of input":"'"+(this.terminals_[W]||W)+"'"),this.parseError(ke,{text:ae.match,token:this.terminals_[W]||W,line:ae.yylineno,loc:de,expected:Ce})}if(U[0]instanceof Array&&U.length>1)throw new Error("Parse Error: multiple actions possible at state: "+xe+", token: "+W);switch(U[0]){case 1:A.push(W),R.push(ae.yytext),F.push(ae.yylloc),A.push(U[1]),W=null,ie=ae.yyleng,K=ae.yytext,ee=ae.yylineno,de=ae.yylloc;break;case 2:if(Ie=this.productions_[U[1]][1],Pe.$=R[R.length-Ie],Pe._$={first_line:F[F.length-(Ie||1)].first_line,last_line:F[F.length-1].last_line,first_column:F[F.length-(Ie||1)].first_column,last_column:F[F.length-1].last_column},X&&(Pe._$.range=[F[F.length-(Ie||1)].range[0],F[F.length-1].range[1]]),Fe=this.performAction.apply(Pe,[K,ie,ee,ne.yy,U[1],R,F].concat(be)),typeof Fe<"u")return Fe;Ie&&(A=A.slice(0,-1*Ie*2),R=R.slice(0,-1*Ie),F=F.slice(0,-1*Ie)),A.push(this.productions_[U[1]][0]),R.push(Pe.$),F.push(Pe._$),Se=j[A[A.length-2]][A[A.length-1]],A.push(Se);break;case 3:return!0}}return!0}},v=function(){var y={EOF:1,parseError:function(_,A){if(this.yy.parser)this.yy.parser.parseError(_,A);else throw new Error(_)},setInput:function(T,_){return this.yy=_||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},input:function(){var T=this._input[0];this.yytext+=T,this.yyleng++,this.offset++,this.match+=T,this.matched+=T;var _=T.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),T},unput:function(T){var _=T.length,A=T.split(/(?:\r\n?|\n)/g);this._input=T+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-_),this.offset-=_;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),A.length-1&&(this.yylineno-=A.length-1);var R=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===P.length?this.yylloc.first_column:0)+P[P.length-A.length].length-A[0].length:this.yylloc.first_column-_},this.options.ranges&&(this.yylloc.range=[R[0],R[0]+this.yyleng-_]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(T){this.unput(this.match.slice(T))},pastInput:function(){var T=this.matched.substr(0,this.matched.length-this.match.length);return(T.length>20?"...":"")+T.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var T=this.pastInput(),_=new Array(T.length+1).join("-");return T+this.upcomingInput()+` +`+_+"^"},test_match:function(T,_){var A,P,R;if(this.options.backtrack_lexer&&(R={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&&(R.yylloc.range=this.yylloc.range.slice(0))),P=T[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+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,_,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),A)return A;if(this._backtrack){for(var F in R)this[F]=R[F];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var T,_,A,P;this._more||(this.yytext="",this.match="");for(var R=this._currentRules(),F=0;F_[0].length)){if(_=A,P=F,this.options.backtrack_lexer){if(T=this.test_match(A,R[F]),T!==!1)return T;if(this._backtrack){_=!1;continue}else return!1}else if(!this.options.flex)break}return _?(T=this.test_match(_,R[P]),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})},lex:function(){var _=this.next();return _||this.lex()},begin:function(_){this.conditionStack.push(_)},popState:function(){var _=this.conditionStack.length-1;return _>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(_){return _=this.conditionStack.length-1-Math.abs(_||0),_>=0?this.conditionStack[_]:"INITIAL"},pushState:function(_){this.begin(_)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(_,A,P,R){switch(P){case 0:return this.pushState("csv"),4;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;case 5:return 20;case 6:return this.popState("escaped_text"),18;case 7:return 19}},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 y}();p.lexer=v;function b(){this.yy={}}return b.prototype=p,p.Parser=b,new b}();iwe.parser=iwe;const NJ=iwe;let PJ=[],BJ=[],tI={};const Oon=()=>{PJ=[],BJ=[],tI={},Pg()};class Non{constructor(s,u,d=0){this.source=s,this.target=u,this.value=d}}const Pon=(i,s,u)=>{PJ.push(new Non(i,s,u))};class Bon{constructor(s){this.ID=s}}const Fon={nodesMap:tI,getConfig:()=>qt().sankey,getNodes:()=>BJ,getLinks:()=>PJ,getGraph:()=>({nodes:BJ.map(i=>({id:i.ID})),links:PJ.map(i=>({source:i.source.ID,target:i.target.ID,value:i.value}))}),addLink:Pon,findOrCreateNode:i=>(i=ci.sanitizeText(i,qt()),tI[i]||(tI[i]=new Bon(i),BJ.push(tI[i])),tI[i]),getAccTitle:Cp,setAccTitle:Bg,getAccDescription:_p,setAccDescription:Sp,getDiagramTitle:Ap,setDiagramTitle:cm,clear:Oon};function vWe(i,s){let u;if(s===void 0)for(const d of i)d!=null&&(u=d)&&(u=d);else{let d=-1;for(let p of i)(p=s(p,++d,i))!=null&&(u=p)&&(u=p)}return u}function wWe(i,s){let u;if(s===void 0)for(const d of i)d!=null&&(u>d||u===void 0&&d>=d)&&(u=d);else{let d=-1;for(let p of i)(p=s(p,++d,i))!=null&&(u>p||u===void 0&&p>=p)&&(u=p)}return u}function swe(i,s){let u=0;if(s===void 0)for(let d of i)(d=+d)&&(u+=d);else{let d=-1;for(let p of i)(p=+s(p,++d,i))&&(u+=p)}return u}function Ron(i){return i.target.depth}function jon(i){return i.depth}function $on(i,s){return s-1-i.height}function yWe(i,s){return i.sourceLinks.length?i.depth:s-1}function zon(i){return i.targetLinks.length?i.depth:i.sourceLinks.length?wWe(i.sourceLinks,Ron)-1:0}function FJ(i){return function(){return i}}function xWe(i,s){return RJ(i.source,s.source)||i.index-s.index}function kWe(i,s){return RJ(i.target,s.target)||i.index-s.index}function RJ(i,s){return i.y0-s.y0}function awe(i){return i.value}function qon(i){return i.index}function Hon(i){return i.nodes}function Von(i){return i.links}function EWe(i,s){const u=i.get(s);if(!u)throw new Error("missing: "+s);return u}function TWe({nodes:i}){for(const s of i){let u=s.y0,d=u;for(const p of s.sourceLinks)p.y0=u+p.width/2,u+=p.width;for(const p of s.targetLinks)p.y1=d+p.width/2,d+=p.width}}function Uon(){let i=0,s=0,u=1,d=1,p=24,v=8,b,y=qon,T=yWe,_,A,P=Hon,R=Von,F=6;function j(){const Pe={nodes:P.apply(null,arguments),links:R.apply(null,arguments)};return K(Pe),ee(Pe),ie(Pe),oe(Pe),ae(Pe),TWe(Pe),Pe}j.update=function(Pe){return TWe(Pe),Pe},j.nodeId=function(Pe){return arguments.length?(y=typeof Pe=="function"?Pe:FJ(Pe),j):y},j.nodeAlign=function(Pe){return arguments.length?(T=typeof Pe=="function"?Pe:FJ(Pe),j):T},j.nodeSort=function(Pe){return arguments.length?(_=Pe,j):_},j.nodeWidth=function(Pe){return arguments.length?(p=+Pe,j):p},j.nodePadding=function(Pe){return arguments.length?(v=b=+Pe,j):v},j.nodes=function(Pe){return arguments.length?(P=typeof Pe=="function"?Pe:FJ(Pe),j):P},j.links=function(Pe){return arguments.length?(R=typeof Pe=="function"?Pe:FJ(Pe),j):R},j.linkSort=function(Pe){return arguments.length?(A=Pe,j):A},j.size=function(Pe){return arguments.length?(i=s=0,u=+Pe[0],d=+Pe[1],j):[u-i,d-s]},j.extent=function(Pe){return arguments.length?(i=+Pe[0][0],u=+Pe[1][0],s=+Pe[0][1],d=+Pe[1][1],j):[[i,s],[u,d]]},j.iterations=function(Pe){return arguments.length?(F=+Pe,j):F};function K({nodes:Pe,links:je}){for(const[Se,Ce]of Pe.entries())Ce.index=Se,Ce.sourceLinks=[],Ce.targetLinks=[];const Ie=new Map(Pe.map((Se,Ce)=>[y(Se,Ce,Pe),Se]));for(const[Se,Ce]of je.entries()){Ce.index=Se;let{source:ke,target:Ke}=Ce;typeof ke!="object"&&(ke=Ce.source=EWe(Ie,ke)),typeof Ke!="object"&&(Ke=Ce.target=EWe(Ie,Ke)),ke.sourceLinks.push(Ce),Ke.targetLinks.push(Ce)}if(A!=null)for(const{sourceLinks:Se,targetLinks:Ce}of Pe)Se.sort(A),Ce.sort(A)}function ee({nodes:Pe}){for(const je of Pe)je.value=je.fixedValue===void 0?Math.max(swe(je.sourceLinks,awe),swe(je.targetLinks,awe)):je.fixedValue}function ie({nodes:Pe}){const je=Pe.length;let Ie=new Set(Pe),Se=new Set,Ce=0;for(;Ie.size;){for(const ke of Ie){ke.depth=Ce;for(const{target:Ke}of ke.sourceLinks)Se.add(Ke)}if(++Ce>je)throw new Error("circular link");Ie=Se,Se=new Set}}function oe({nodes:Pe}){const je=Pe.length;let Ie=new Set(Pe),Se=new Set,Ce=0;for(;Ie.size;){for(const ke of Ie){ke.height=Ce;for(const{source:Ke}of ke.targetLinks)Se.add(Ke)}if(++Ce>je)throw new Error("circular link");Ie=Se,Se=new Set}}function pe({nodes:Pe}){const je=vWe(Pe,Ce=>Ce.depth)+1,Ie=(u-i-p)/(je-1),Se=new Array(je);for(const Ce of Pe){const ke=Math.max(0,Math.min(je-1,Math.floor(T.call(null,Ce,je))));Ce.layer=ke,Ce.x0=i+ke*Ie,Ce.x1=Ce.x0+p,Se[ke]?Se[ke].push(Ce):Se[ke]=[Ce]}if(_)for(const Ce of Se)Ce.sort(_);return Se}function be(Pe){const je=wWe(Pe,Ie=>(d-s-(Ie.length-1)*b)/swe(Ie,awe));for(const Ie of Pe){let Se=s;for(const Ce of Ie){Ce.y0=Se,Ce.y1=Se+Ce.value*je,Se=Ce.y1+b;for(const ke of Ce.sourceLinks)ke.width=ke.value*je}Se=(d-Se+b)/(Ie.length+1);for(let Ce=0;CeIe.length)-1)),be(je);for(let Ie=0;Ie0))continue;let gn=(Ft/Ne-Ke.y0)*je;Ke.y0+=gn,Ke.y1+=gn,W(Ke)}_===void 0&&ke.sort(RJ),de(ke,Ie)}}function se(Pe,je,Ie){for(let Se=Pe.length,Ce=Se-2;Ce>=0;--Ce){const ke=Pe[Ce];for(const Ke of ke){let Ft=0,Ne=0;for(const{target:_t,value:Et}of Ke.sourceLinks){let Gt=Et*(_t.layer-Ke.layer);Ft+=Fe(Ke,_t)*Gt,Ne+=Gt}if(!(Ne>0))continue;let gn=(Ft/Ne-Ke.y0)*je;Ke.y0+=gn,Ke.y1+=gn,W(Ke)}_===void 0&&ke.sort(RJ),de(ke,Ie)}}function de(Pe,je){const Ie=Pe.length>>1,Se=Pe[Ie];ge(Pe,Se.y0-b,Ie-1,je),X(Pe,Se.y1+b,Ie+1,je),ge(Pe,d,Pe.length-1,je),X(Pe,s,0,je)}function X(Pe,je,Ie,Se){for(;Ie1e-6&&(Ce.y0+=ke,Ce.y1+=ke),je=Ce.y1+b}}function ge(Pe,je,Ie,Se){for(;Ie>=0;--Ie){const Ce=Pe[Ie],ke=(Ce.y1-je)*Se;ke>1e-6&&(Ce.y0-=ke,Ce.y1-=ke),je=Ce.y0-b}}function W({sourceLinks:Pe,targetLinks:je}){if(A===void 0){for(const{source:{sourceLinks:Ie}}of je)Ie.sort(kWe);for(const{target:{targetLinks:Ie}}of Pe)Ie.sort(xWe)}}function xe(Pe){if(A===void 0)for(const{sourceLinks:je,targetLinks:Ie}of Pe)je.sort(kWe),Ie.sort(xWe)}function U(Pe,je){let Ie=Pe.y0-(Pe.sourceLinks.length-1)*b/2;for(const{target:Se,width:Ce}of Pe.sourceLinks){if(Se===je)break;Ie+=Ce+b}for(const{source:Se,width:Ce}of je.targetLinks){if(Se===Pe)break;Ie-=Ce}return Ie}function Fe(Pe,je){let Ie=je.y0-(je.targetLinks.length-1)*b/2;for(const{source:Se,width:Ce}of je.targetLinks){if(Se===Pe)break;Ie+=Ce+b}for(const{target:Se,width:Ce}of Pe.sourceLinks){if(Se===je)break;Ie-=Ce}return Ie}return j}var owe=Math.PI,cwe=2*owe,aS=1e-6,Gon=cwe-aS;function uwe(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function CWe(){return new uwe}uwe.prototype=CWe.prototype={constructor:uwe,moveTo:function(i,s){this._+="M"+(this._x0=this._x1=+i)+","+(this._y0=this._y1=+s)},closePath:function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(i,s){this._+="L"+(this._x1=+i)+","+(this._y1=+s)},quadraticCurveTo:function(i,s,u,d){this._+="Q"+ +i+","+ +s+","+(this._x1=+u)+","+(this._y1=+d)},bezierCurveTo:function(i,s,u,d,p,v){this._+="C"+ +i+","+ +s+","+ +u+","+ +d+","+(this._x1=+p)+","+(this._y1=+v)},arcTo:function(i,s,u,d,p){i=+i,s=+s,u=+u,d=+d,p=+p;var v=this._x1,b=this._y1,y=u-i,T=d-s,_=v-i,A=b-s,P=_*_+A*A;if(p<0)throw new Error("negative radius: "+p);if(this._x1===null)this._+="M"+(this._x1=i)+","+(this._y1=s);else if(P>aS)if(!(Math.abs(A*y-T*_)>aS)||!p)this._+="L"+(this._x1=i)+","+(this._y1=s);else{var R=u-v,F=d-b,j=y*y+T*T,K=R*R+F*F,ee=Math.sqrt(j),ie=Math.sqrt(P),oe=p*Math.tan((owe-Math.acos((j+P-K)/(2*ee*ie)))/2),pe=oe/ie,be=oe/ee;Math.abs(pe-1)>aS&&(this._+="L"+(i+pe*_)+","+(s+pe*A)),this._+="A"+p+","+p+",0,0,"+ +(A*R>_*F)+","+(this._x1=i+be*y)+","+(this._y1=s+be*T)}},arc:function(i,s,u,d,p,v){i=+i,s=+s,u=+u,v=!!v;var b=u*Math.cos(d),y=u*Math.sin(d),T=i+b,_=s+y,A=1^v,P=v?d-p:p-d;if(u<0)throw new Error("negative radius: "+u);this._x1===null?this._+="M"+T+","+_:(Math.abs(this._x1-T)>aS||Math.abs(this._y1-_)>aS)&&(this._+="L"+T+","+_),u&&(P<0&&(P=P%cwe+cwe),P>Gon?this._+="A"+u+","+u+",0,1,"+A+","+(i-b)+","+(s-y)+"A"+u+","+u+",0,1,"+A+","+(this._x1=T)+","+(this._y1=_):P>aS&&(this._+="A"+u+","+u+",0,"+ +(P>=owe)+","+A+","+(this._x1=i+u*Math.cos(p))+","+(this._y1=s+u*Math.sin(p))))},rect:function(i,s,u,d){this._+="M"+(this._x0=this._x1=+i)+","+(this._y0=this._y1=+s)+"h"+ +u+"v"+ +d+"h"+-u+"Z"},toString:function(){return this._}};function SWe(i){return function(){return i}}function Kon(i){return i[0]}function Won(i){return i[1]}var Yon=Array.prototype.slice;function Xon(i){return i.source}function Qon(i){return i.target}function Jon(i){var s=Xon,u=Qon,d=Kon,p=Won,v=null;function b(){var y,T=Yon.call(arguments),_=s.apply(this,T),A=u.apply(this,T);if(v||(v=y=CWe()),i(v,+d.apply(this,(T[0]=_,T)),+p.apply(this,T),+d.apply(this,(T[0]=A,T)),+p.apply(this,T)),y)return v=null,y+""||null}return b.source=function(y){return arguments.length?(s=y,b):s},b.target=function(y){return arguments.length?(u=y,b):u},b.x=function(y){return arguments.length?(d=typeof y=="function"?y:SWe(+y),b):d},b.y=function(y){return arguments.length?(p=typeof y=="function"?y:SWe(+y),b):p},b.context=function(y){return arguments.length?(v=y??null,b):v},b}function Zon(i,s,u,d,p){i.moveTo(s,u),i.bezierCurveTo(s=(s+d)/2,u,s,p,d,p)}function ecn(){return Jon(Zon)}function tcn(i){return[i.source.x1,i.y0]}function ncn(i){return[i.target.x0,i.y1]}function rcn(){return ecn().source(tcn).target(ncn)}const _We=class aBe{static next(s){return new aBe(s+ ++aBe.count)}constructor(s){this.id=s,this.href=`#${s}`}toString(){return"url("+this.href+")"}};_We.count=0;let AWe=_We;const icn={left:jon,right:$on,center:zon,justify:yWe},scn={draw:function(i,s,u,d){const{securityLevel:p,sankey:v}=qt(),b=Zje.sankey;let y;p==="sandbox"&&(y=Ir("#i"+s));const T=Ir(p==="sandbox"?y.nodes()[0].contentDocument.body:"body"),_=p==="sandbox"?T.select(`[id="${s}"]`):Ir(`[id="${s}"]`),A=(v==null?void 0:v.width)??b.width,P=(v==null?void 0:v.height)??b.width,R=(v==null?void 0:v.useMaxWidth)??b.useMaxWidth,F=(v==null?void 0:v.nodeAlignment)??b.nodeAlignment,j=(v==null?void 0:v.prefix)??b.prefix,K=(v==null?void 0:v.suffix)??b.suffix,ee=(v==null?void 0:v.showValues)??b.showValues,ie=d.db.getGraph(),oe=icn[F],pe=10;Uon().nodeId(ge=>ge.id).nodeWidth(pe).nodePadding(10+(ee?15:0)).nodeAlign(oe).extent([[0,0],[A,P]])(ie);const ae=_F(zFe);_.append("g").attr("class","nodes").selectAll(".node").data(ie.nodes).join("g").attr("class","node").attr("id",ge=>(ge.uid=AWe.next("node-")).id).attr("transform",function(ge){return"translate("+ge.x0+","+ge.y0+")"}).attr("x",ge=>ge.x0).attr("y",ge=>ge.y0).append("rect").attr("height",ge=>ge.y1-ge.y0).attr("width",ge=>ge.x1-ge.x0).attr("fill",ge=>ae(ge.id));const ne=({id:ge,value:W})=>ee?`${ge} +${j}${Math.round(W*100)/100}${K}`:ge;_.append("g").attr("class","node-labels").attr("font-family","sans-serif").attr("font-size",14).selectAll("text").data(ie.nodes).join("text").attr("x",ge=>ge.x0(ge.y1+ge.y0)/2).attr("dy",`${ee?"0":"0.35"}em`).attr("text-anchor",ge=>ge.x0(W.uid=AWe.next("linearGradient-")).id).attr("gradientUnits","userSpaceOnUse").attr("x1",W=>W.source.x1).attr("x2",W=>W.target.x0);ge.append("stop").attr("offset","0%").attr("stop-color",W=>ae(W.source.id)),ge.append("stop").attr("offset","100%").attr("stop-color",W=>ae(W.target.id))}let X;switch(de){case"gradient":X=ge=>ge.uid;break;case"source":X=ge=>ae(ge.source.id);break;case"target":X=ge=>ae(ge.target.id);break;default:X=de}se.append("path").attr("d",rcn()).attr("stroke",X).attr("stroke-width",ge=>Math.max(1,ge.width)),y9(void 0,_,0,R)}},acn=i=>i.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,` +`).trim(),ocn=NJ.parse.bind(NJ);NJ.parse=i=>ocn(acn(i));const ccn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:NJ,db:Fon,renderer:scn}},Symbol.toStringTag,{value:"Module"}));var lwe=function(){var i=function(pe,be,ae,ne){for(ae=ae||{},ne=pe.length;ne--;ae[pe[ne]]=be);return ae},s=[1,7],u=[1,13],d=[1,14],p=[1,15],v=[1,19],b=[1,16],y=[1,17],T=[1,18],_=[8,30],A=[8,21,28,29,30,31,32,40,44,47],P=[1,23],R=[1,24],F=[8,15,16,21,28,29,30,31,32,40,44,47],j=[8,15,16,21,27,28,29,30,31,32,40,44,47],K=[1,49],ee={trace:function(){},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:function(be,ae,ne,se,de,X,ge){var W=X.length-1;switch(de){case 4:se.getLogger().debug("Rule: separator (NL) ");break;case 5:se.getLogger().debug("Rule: separator (Space) ");break;case 6:se.getLogger().debug("Rule: separator (EOF) ");break;case 7:se.getLogger().debug("Rule: hierarchy: ",X[W-1]),se.setHierarchy(X[W-1]);break;case 8:se.getLogger().debug("Stop NL ");break;case 9:se.getLogger().debug("Stop EOF ");break;case 10:se.getLogger().debug("Stop NL2 ");break;case 11:se.getLogger().debug("Stop EOF2 ");break;case 12:se.getLogger().debug("Rule: statement: ",X[W]),typeof X[W].length=="number"?this.$=X[W]:this.$=[X[W]];break;case 13:se.getLogger().debug("Rule: statement #2: ",X[W-1]),this.$=[X[W-1]].concat(X[W]);break;case 14:se.getLogger().debug("Rule: link: ",X[W],be),this.$={edgeTypeStr:X[W],label:""};break;case 15:se.getLogger().debug("Rule: LABEL link: ",X[W-3],X[W-1],X[W]),this.$={edgeTypeStr:X[W],label:X[W-1]};break;case 18:const xe=parseInt(X[W]),U=se.generateId();this.$={id:U,type:"space",label:"",width:xe,children:[]};break;case 23:se.getLogger().debug("Rule: (nodeStatement link node) ",X[W-2],X[W-1],X[W]," typestr: ",X[W-1].edgeTypeStr);const Fe=se.edgeStrToEdgeData(X[W-1].edgeTypeStr);this.$=[{id:X[W-2].id,label:X[W-2].label,type:X[W-2].type,directions:X[W-2].directions},{id:X[W-2].id+"-"+X[W].id,start:X[W-2].id,end:X[W].id,label:X[W-1].label,type:"edge",directions:X[W].directions,arrowTypeEnd:Fe,arrowTypeStart:"arrow_open"},{id:X[W].id,label:X[W].label,type:se.typeStr2Type(X[W].typeStr),directions:X[W].directions}];break;case 24:se.getLogger().debug("Rule: nodeStatement (abc88 node size) ",X[W-1],X[W]),this.$={id:X[W-1].id,label:X[W-1].label,type:se.typeStr2Type(X[W-1].typeStr),directions:X[W-1].directions,widthInColumns:parseInt(X[W],10)};break;case 25:se.getLogger().debug("Rule: nodeStatement (node) ",X[W]),this.$={id:X[W].id,label:X[W].label,type:se.typeStr2Type(X[W].typeStr),directions:X[W].directions,widthInColumns:1};break;case 26:se.getLogger().debug("APA123",this?this:"na"),se.getLogger().debug("COLUMNS: ",X[W]),this.$={type:"column-setting",columns:X[W]==="auto"?-1:parseInt(X[W])};break;case 27:se.getLogger().debug("Rule: id-block statement : ",X[W-2],X[W-1]),se.generateId(),this.$={...X[W-2],type:"composite",children:X[W-1]};break;case 28:se.getLogger().debug("Rule: blockStatement : ",X[W-2],X[W-1],X[W]);const Pe=se.generateId();this.$={id:Pe,type:"composite",label:"",children:X[W-1]};break;case 29:se.getLogger().debug("Rule: node (NODE_ID separator): ",X[W]),this.$={id:X[W]};break;case 30:se.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",X[W-1],X[W]),this.$={id:X[W-1],label:X[W].label,typeStr:X[W].typeStr,directions:X[W].directions};break;case 31:se.getLogger().debug("Rule: dirList: ",X[W]),this.$=[X[W]];break;case 32:se.getLogger().debug("Rule: dirList: ",X[W-1],X[W]),this.$=[X[W-1]].concat(X[W]);break;case 33:se.getLogger().debug("Rule: nodeShapeNLabel: ",X[W-2],X[W-1],X[W]),this.$={typeStr:X[W-2]+X[W],label:X[W-1]};break;case 34:se.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",X[W-3],X[W-2]," #3:",X[W-1],X[W]),this.$={typeStr:X[W-3]+X[W],label:X[W-2],directions:X[W-1]};break;case 35:case 36:this.$={type:"classDef",id:X[W-1].trim(),css:X[W].trim()};break;case 37:this.$={type:"applyClass",id:X[W-1].trim(),styleClass:X[W].trim()};break;case 38:this.$={type:"applyStyles",id:X[W-1].trim(),stylesStr:X[W].trim()};break}},table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:s,22:8,23:9,24:10,25:11,26:12,28:u,29:d,31:p,32:v,40:b,44:y,47:T},{8:[1,20]},i(_,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:s,28:u,29:d,31:p,32:v,40:b,44:y,47:T}),i(A,[2,16],{14:22,15:P,16:R}),i(A,[2,17]),i(A,[2,18]),i(A,[2,19]),i(A,[2,20]),i(A,[2,21]),i(A,[2,22]),i(F,[2,25],{27:[1,25]}),i(A,[2,26]),{19:26,26:12,32:v},{11:27,13:4,19:5,20:6,21:s,22:8,23:9,24:10,25:11,26:12,28:u,29:d,31:p,32:v,40:b,44:y,47:T},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},i(j,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},i(_,[2,13]),{26:35,32:v},{32:[2,14]},{17:[1,36]},i(F,[2,24]),{11:37,13:4,14:22,15:P,16:R,19:5,20:6,21:s,22:8,23:9,24:10,25:11,26:12,28:u,29:d,31:p,32:v,40:b,44:y,47:T},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},i(j,[2,30]),{18:[1,43]},{18:[1,44]},i(F,[2,23]),{18:[1,45]},{30:[1,46]},i(A,[2,28]),i(A,[2,35]),i(A,[2,36]),i(A,[2,37]),i(A,[2,38]),{37:[1,47]},{34:48,35:K},{15:[1,50]},i(A,[2,27]),i(j,[2,33]),{39:[1,51]},{34:52,35:K,39:[2,31]},{32:[2,15]},i(j,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:function(be,ae){if(ae.recoverable)this.trace(be);else{var ne=new Error(be);throw ne.hash=ae,ne}},parse:function(be){var ae=this,ne=[0],se=[],de=[null],X=[],ge=this.table,W="",xe=0,U=0,Fe=2,Pe=1,je=X.slice.call(arguments,1),Ie=Object.create(this.lexer),Se={yy:{}};for(var Ce in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ce)&&(Se.yy[Ce]=this.yy[Ce]);Ie.setInput(be,Se.yy),Se.yy.lexer=Ie,Se.yy.parser=this,typeof Ie.yylloc>"u"&&(Ie.yylloc={});var ke=Ie.yylloc;X.push(ke);var Ke=Ie.options&&Ie.options.ranges;typeof Se.yy.parseError=="function"?this.parseError=Se.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ft(){var kt;return kt=se.pop()||Ie.lex()||Pe,typeof kt!="number"&&(kt instanceof Array&&(se=kt,kt=se.pop()),kt=ae.symbols_[kt]||kt),kt}for(var Ne,gn,_t,Et,Gt={},ln,xt,Pt,Qe;;){if(gn=ne[ne.length-1],this.defaultActions[gn]?_t=this.defaultActions[gn]:((Ne===null||typeof Ne>"u")&&(Ne=Ft()),_t=ge[gn]&&ge[gn][Ne]),typeof _t>"u"||!_t.length||!_t[0]){var Dt="";Qe=[];for(ln in ge[gn])this.terminals_[ln]&&ln>Fe&&Qe.push("'"+this.terminals_[ln]+"'");Ie.showPosition?Dt="Parse error on line "+(xe+1)+`: +`+Ie.showPosition()+` +Expecting `+Qe.join(", ")+", got '"+(this.terminals_[Ne]||Ne)+"'":Dt="Parse error on line "+(xe+1)+": Unexpected "+(Ne==Pe?"end of input":"'"+(this.terminals_[Ne]||Ne)+"'"),this.parseError(Dt,{text:Ie.match,token:this.terminals_[Ne]||Ne,line:Ie.yylineno,loc:ke,expected:Qe})}if(_t[0]instanceof Array&&_t.length>1)throw new Error("Parse Error: multiple actions possible at state: "+gn+", token: "+Ne);switch(_t[0]){case 1:ne.push(Ne),de.push(Ie.yytext),X.push(Ie.yylloc),ne.push(_t[1]),Ne=null,U=Ie.yyleng,W=Ie.yytext,xe=Ie.yylineno,ke=Ie.yylloc;break;case 2:if(xt=this.productions_[_t[1]][1],Gt.$=de[de.length-xt],Gt._$={first_line:X[X.length-(xt||1)].first_line,last_line:X[X.length-1].last_line,first_column:X[X.length-(xt||1)].first_column,last_column:X[X.length-1].last_column},Ke&&(Gt._$.range=[X[X.length-(xt||1)].range[0],X[X.length-1].range[1]]),Et=this.performAction.apply(Gt,[W,U,xe,Se.yy,_t[1],de,X].concat(je)),typeof Et<"u")return Et;xt&&(ne=ne.slice(0,-1*xt*2),de=de.slice(0,-1*xt),X=X.slice(0,-1*xt)),ne.push(this.productions_[_t[1]][0]),de.push(Gt.$),X.push(Gt._$),Pt=ge[ne[ne.length-2]][ne[ne.length-1]],ne.push(Pt);break;case 3:return!0}}return!0}},ie=function(){var pe={EOF:1,parseError:function(ae,ne){if(this.yy.parser)this.yy.parser.parseError(ae,ne);else throw new Error(ae)},setInput:function(be,ae){return this.yy=ae||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},input:function(){var be=this._input[0];this.yytext+=be,this.yyleng++,this.offset++,this.match+=be,this.matched+=be;var ae=be.match(/(?:\r\n?|\n).*/g);return ae?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),be},unput:function(be){var ae=be.length,ne=be.split(/(?:\r\n?|\n)/g);this._input=be+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-ae),this.offset-=ae;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),ne.length-1&&(this.yylineno-=ne.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:ne?(ne.length===se.length?this.yylloc.first_column:0)+se[se.length-ne.length].length-ne[0].length:this.yylloc.first_column-ae},this.options.ranges&&(this.yylloc.range=[de[0],de[0]+this.yyleng-ae]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject: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},less:function(be){this.unput(this.match.slice(be))},pastInput:function(){var be=this.matched.substr(0,this.matched.length-this.match.length);return(be.length>20?"...":"")+be.substr(-20).replace(/\n/g,"")},upcomingInput: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,"")},showPosition:function(){var be=this.pastInput(),ae=new Array(be.length+1).join("-");return be+this.upcomingInput()+` +`+ae+"^"},test_match:function(be,ae){var ne,se,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))),se=be[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+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],ne=this.performAction.call(this,this.yy,this,ae,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ne)return ne;if(this._backtrack){for(var X in de)this[X]=de[X];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var be,ae,ne,se;this._more||(this.yytext="",this.match="");for(var de=this._currentRules(),X=0;Xae[0].length)){if(ae=ne,se=X,this.options.backtrack_lexer){if(be=this.test_match(ne,de[X]),be!==!1)return be;if(this._backtrack){ae=!1;continue}else return!1}else if(!this.options.flex)break}return ae?(be=this.test_match(ae,de[se]),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})},lex:function(){var ae=this.next();return ae||this.lex()},begin:function(ae){this.conditionStack.push(ae)},popState:function(){var ae=this.conditionStack.length-1;return ae>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(ae){return ae=this.conditionStack.length-1-Math.abs(ae||0),ae>=0?this.conditionStack[ae]:"INITIAL"},pushState:function(ae){this.begin(ae)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(ae,ne,se,de){switch(se){case 0:return 10;case 1:return ae.getLogger().debug("Found space-block"),31;case 2:return ae.getLogger().debug("Found nl-block"),31;case 3:return ae.getLogger().debug("Found space-block"),29;case 4:ae.getLogger().debug(".",ne.yytext);break;case 5:ae.getLogger().debug("_",ne.yytext);break;case 6:return 5;case 7:return ne.yytext=-1,28;case 8:return ne.yytext=ne.yytext.replace(/columns\s+/,""),ae.getLogger().debug("COLUMNS (LEX)",ne.yytext),28;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:ae.getLogger().debug("LEX: POPPING STR:",ne.yytext),this.popState();break;case 14:return ae.getLogger().debug("LEX: STR end:",ne.yytext),"STR";case 15:return ne.yytext=ne.yytext.replace(/space\:/,""),ae.getLogger().debug("SPACE NUM (LEX)",ne.yytext),21;case 16:return ne.yytext="1",ae.getLogger().debug("COLUMNS (LEX)",ne.yytext),21;case 17:return 43;case 18:return"LINKSTYLE";case 19:return"INTERPOLATE";case 20:return this.pushState("CLASSDEF"),40;case 21:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 22:return this.popState(),this.pushState("CLASSDEFID"),41;case 23:return this.popState(),42;case 24:return this.pushState("CLASS"),44;case 25:return this.popState(),this.pushState("CLASS_STYLE"),45;case 26:return this.popState(),46;case 27:return this.pushState("STYLE_STMNT"),47;case 28:return this.popState(),this.pushState("STYLE_DEFINITION"),48;case 29:return this.popState(),49;case 30:return this.pushState("acc_title"),"acc_title";case 31:return this.popState(),"acc_title_value";case 32:return this.pushState("acc_descr"),"acc_descr";case 33:return this.popState(),"acc_descr_value";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(),ae.getLogger().debug("Lex: (("),"NODE_DEND";case 39:return this.popState(),ae.getLogger().debug("Lex: (("),"NODE_DEND";case 40:return this.popState(),ae.getLogger().debug("Lex: ))"),"NODE_DEND";case 41:return this.popState(),ae.getLogger().debug("Lex: (("),"NODE_DEND";case 42:return this.popState(),ae.getLogger().debug("Lex: (("),"NODE_DEND";case 43:return this.popState(),ae.getLogger().debug("Lex: (-"),"NODE_DEND";case 44:return this.popState(),ae.getLogger().debug("Lex: -)"),"NODE_DEND";case 45:return this.popState(),ae.getLogger().debug("Lex: (("),"NODE_DEND";case 46:return this.popState(),ae.getLogger().debug("Lex: ]]"),"NODE_DEND";case 47:return this.popState(),ae.getLogger().debug("Lex: ("),"NODE_DEND";case 48:return this.popState(),ae.getLogger().debug("Lex: ])"),"NODE_DEND";case 49:return this.popState(),ae.getLogger().debug("Lex: /]"),"NODE_DEND";case 50:return this.popState(),ae.getLogger().debug("Lex: /]"),"NODE_DEND";case 51:return this.popState(),ae.getLogger().debug("Lex: )]"),"NODE_DEND";case 52:return this.popState(),ae.getLogger().debug("Lex: )"),"NODE_DEND";case 53:return this.popState(),ae.getLogger().debug("Lex: ]>"),"NODE_DEND";case 54:return this.popState(),ae.getLogger().debug("Lex: ]"),"NODE_DEND";case 55:return ae.getLogger().debug("Lexa: -)"),this.pushState("NODE"),36;case 56:return ae.getLogger().debug("Lexa: (-"),this.pushState("NODE"),36;case 57:return ae.getLogger().debug("Lexa: ))"),this.pushState("NODE"),36;case 58:return ae.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 59:return ae.getLogger().debug("Lex: ((("),this.pushState("NODE"),36;case 60:return ae.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 61:return ae.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 62:return ae.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 63:return ae.getLogger().debug("Lexc: >"),this.pushState("NODE"),36;case 64:return ae.getLogger().debug("Lexa: (["),this.pushState("NODE"),36;case 65:return ae.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 66:return this.pushState("NODE"),36;case 67:return this.pushState("NODE"),36;case 68:return this.pushState("NODE"),36;case 69:return this.pushState("NODE"),36;case 70:return this.pushState("NODE"),36;case 71:return this.pushState("NODE"),36;case 72:return this.pushState("NODE"),36;case 73:return ae.getLogger().debug("Lexa: ["),this.pushState("NODE"),36;case 74:return this.pushState("BLOCK_ARROW"),ae.getLogger().debug("LEX ARR START"),38;case 75:return ae.getLogger().debug("Lex: NODE_ID",ne.yytext),32;case 76:return ae.getLogger().debug("Lex: EOF",ne.yytext),8;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:ae.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 82:ae.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 83:return ae.getLogger().debug("LEX: NODE_DESCR:",ne.yytext),"NODE_DESCR";case 84:ae.getLogger().debug("LEX POPPING"),this.popState();break;case 85:ae.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 86:return ne.yytext=ne.yytext.replace(/^,\s*/,""),ae.getLogger().debug("Lex (right): dir:",ne.yytext),"DIR";case 87:return ne.yytext=ne.yytext.replace(/^,\s*/,""),ae.getLogger().debug("Lex (left):",ne.yytext),"DIR";case 88:return ne.yytext=ne.yytext.replace(/^,\s*/,""),ae.getLogger().debug("Lex (x):",ne.yytext),"DIR";case 89:return ne.yytext=ne.yytext.replace(/^,\s*/,""),ae.getLogger().debug("Lex (y):",ne.yytext),"DIR";case 90:return ne.yytext=ne.yytext.replace(/^,\s*/,""),ae.getLogger().debug("Lex (up):",ne.yytext),"DIR";case 91:return ne.yytext=ne.yytext.replace(/^,\s*/,""),ae.getLogger().debug("Lex (down):",ne.yytext),"DIR";case 92:return ne.yytext="]>",ae.getLogger().debug("Lex (ARROW_DIR end):",ne.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";case 93:return ae.getLogger().debug("Lex: LINK","#"+ne.yytext+"#"),15;case 94:return ae.getLogger().debug("Lex: LINK",ne.yytext),15;case 95:return ae.getLogger().debug("Lex: LINK",ne.yytext),15;case 96:return ae.getLogger().debug("Lex: LINK",ne.yytext),15;case 97:return ae.getLogger().debug("Lex: START_LINK",ne.yytext),this.pushState("LLABEL"),16;case 98:return ae.getLogger().debug("Lex: START_LINK",ne.yytext),this.pushState("LLABEL"),16;case 99:return ae.getLogger().debug("Lex: START_LINK",ne.yytext),this.pushState("LLABEL"),16;case 100:this.pushState("md_string");break;case 101:return ae.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";case 102:return this.popState(),ae.getLogger().debug("Lex: LINK","#"+ne.yytext+"#"),15;case 103:return this.popState(),ae.getLogger().debug("Lex: LINK",ne.yytext),15;case 104:return this.popState(),ae.getLogger().debug("Lex: LINK",ne.yytext),15;case 105:return ae.getLogger().debug("Lex: COLON",ne.yytext),ne.yytext=ne.yytext.slice(1),27}},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 pe}();ee.lexer=ie;function oe(){this.yy={}}return oe.prototype=ee,ee.Parser=oe,new oe}();lwe.parser=lwe;const ucn=lwe;let U2={},hwe=[],ij={};const LWe="color",MWe="fill",lcn="bgFill",DWe=",",hcn=qt();let sj={};const fcn=i=>ci.sanitizeText(i,hcn),dcn=function(i,s=""){sj[i]===void 0&&(sj[i]={id:i,styles:[],textStyles:[]});const u=sj[i];s!=null&&s.split(DWe).forEach(d=>{const p=d.replace(/([^;]*);/,"$1").trim();if(d.match(LWe)){const b=p.replace(MWe,lcn).replace(LWe,MWe);u.textStyles.push(b)}u.styles.push(p)})},gcn=function(i,s=""){const u=U2[i];s!=null&&(u.styles=s.split(DWe))},pcn=function(i,s){i.split(",").forEach(function(u){let d=U2[u];if(d===void 0){const p=u.trim();U2[p]={id:p,type:"na",children:[]},d=U2[p]}d.classes||(d.classes=[]),d.classes.push(s)})},IWe=(i,s)=>{const u=i.flat(),d=[];for(const p of u){if(p.label&&(p.label=fcn(p.label)),p.type==="classDef"){dcn(p.id,p.css);continue}if(p.type==="applyClass"){pcn(p.id,(p==null?void 0:p.styleClass)||"");continue}if(p.type==="applyStyles"){p!=null&&p.stylesStr&&gcn(p.id,p==null?void 0:p.stylesStr);continue}if(p.type==="column-setting")s.columns=p.columns||-1;else if(p.type==="edge")ij[p.id]?ij[p.id]++:ij[p.id]=1,p.id=ij[p.id]+"-"+p.id,hwe.push(p);else{p.label||(p.type==="composite"?p.label="":p.label=p.id);const v=!U2[p.id];if(v?U2[p.id]=p:(p.type!=="na"&&(U2[p.id].type=p.type),p.label!==p.id&&(U2[p.id].label=p.label)),p.children&&IWe(p.children,p),p.type==="space"){const b=p.width||1;for(let y=0;y{Xe.debug("Clear called"),Pg(),aj={id:"root",type:"composite",children:[],columns:-1},U2={root:aj},fwe=[],sj={},hwe=[],ij={}};function mcn(i){switch(Xe.debug("typeStr2Type",i),i){case"[]":return"square";case"()":return Xe.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 vcn(i){switch(Xe.debug("typeStr2Type",i),i){case"==":return"thick";default:return"normal"}}function wcn(i){switch(i.trim()){case"--x":return"arrow_cross";case"--o":return"arrow_circle";default:return"arrow_point"}}let OWe=0;const ycn={getConfig:()=>Vh().block,typeStr2Type:mcn,edgeTypeStr2Type:vcn,edgeStrToEdgeData:wcn,getLogger:()=>console,getBlocksFlat:()=>[...Object.values(U2)],getBlocks:()=>fwe||[],getEdges:()=>hwe,setHierarchy:i=>{aj.children=i,IWe(i,aj),fwe=aj.children},getBlock:i=>U2[i],setBlock:i=>{U2[i.id]=i},getColumns:i=>{const s=U2[i];return s?s.columns?s.columns:s.children?s.children.length:-1:-1},getClasses:function(){return sj},clear:bcn,generateId:()=>(OWe++,"id-"+Math.random().toString(36).substr(2,12)+"-"+OWe)},jJ=(i,s)=>{const u=ARe,d=u(i,"r"),p=u(i,"g"),v=u(i,"b");return SC(d,p,v,s)},xcn=i=>`.label { + font-family: ${i.fontFamily}; + color: ${i.nodeTextColor||i.textColor}; + } + .cluster-label text { + fill: ${i.titleColor}; + } + .cluster-label span,p { + color: ${i.titleColor}; + } + + + + .label text,span,p { + fill: ${i.nodeTextColor||i.textColor}; + color: ${i.nodeTextColor||i.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${i.mainBkg}; + stroke: ${i.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: ${i.arrowheadColor}; + } + + .edgePath .path { + stroke: ${i.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${i.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${i.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${i.edgeLabelBackground}; + fill: ${i.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${jJ(i.edgeLabelBackground,.5)}; + // background-color: + } + + .node .cluster { + // fill: ${jJ(i.mainBkg,.5)}; + fill: ${jJ(i.clusterBkg,.5)}; + stroke: ${jJ(i.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: ${i.titleColor}; + } + + .cluster span,p { + color: ${i.titleColor}; + } + /* .cluster div { + color: ${i.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${i.fontFamily}; + font-size: 12px; + background: ${i.tertiaryColor}; + border: 1px solid ${i.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${i.textColor}; + } +`;function NWe(i,s,u=!1){var R,F,j;const d=i;let p="default";(((R=d==null?void 0:d.classes)==null?void 0:R.length)||0)>0&&(p=((d==null?void 0:d.classes)||[]).join(" ")),p=p+" flowchart-label";let v=0,b="",y;switch(d.type){case"round":v=5,b="rect";break;case"composite":v=0,b="composite",y=0;break;case"square":b="rect";break;case"diamond":b="question";break;case"hexagon":b="hexagon";break;case"block_arrow":b="block_arrow";break;case"odd":b="rect_left_inv_arrow";break;case"lean_right":b="lean_right";break;case"lean_left":b="lean_left";break;case"trapezoid":b="trapezoid";break;case"inv_trapezoid":b="inv_trapezoid";break;case"rect_left_inv_arrow":b="rect_left_inv_arrow";break;case"circle":b="circle";break;case"ellipse":b="ellipse";break;case"stadium":b="stadium";break;case"subroutine":b="subroutine";break;case"cylinder":b="cylinder";break;case"group":b="rect";break;case"doublecircle":b="doublecircle";break;default:b="rect"}const T=om((d==null?void 0:d.styles)||[]),_=d.label,A=d.size||{width:0,height:0,x:0,y:0};return{labelStyle:T.labelStyle,shape:b,labelText:_,rx:v,ry:v,class:p,style:T.style,id:d.id,directions:d.directions,width:A.width,height:A.height,x:A.x,y:A.y,positioned:u,intersect:void 0,type:d.type,padding:y??(((j=(F=Vh())==null?void 0:F.block)==null?void 0:j.padding)||0)}}async function kcn(i,s,u){const d=NWe(s,u,!1);if(d.type==="group")return;const p=await tJ(i,d),v=p.node().getBBox(),b=u.getBlock(d.id);b.size={width:v.width,height:v.height,x:0,y:0,node:p},u.setBlock(b),p.remove()}async function Ecn(i,s,u){const d=NWe(s,u,!0);u.getBlock(d.id).type!=="space"&&(await tJ(i,d),s.intersect=d==null?void 0:d.intersect,$me(d))}async function dwe(i,s,u,d){for(const p of s)await d(i,p,u),p.children&&await dwe(i,p.children,u,d)}async function Tcn(i,s,u){await dwe(i,s,u,kcn)}async function Ccn(i,s,u){await dwe(i,s,u,Ecn)}async function Scn(i,s,u,d,p){const v=new B0({multigraph:!0,compound:!0});v.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(const b of u)b.size&&v.setNode(b.id,{width:b.size.width,height:b.size.height,intersect:b.intersect});for(const b of s)if(b.start&&b.end){const y=d.getBlock(b.start),T=d.getBlock(b.end);if(y!=null&&y.size&&(T!=null&&T.size)){const _=y.size,A=T.size,P=[{x:_.x,y:_.y},{x:_.x+(A.x-_.x)/2,y:_.y+(A.y-_.y)/2},{x:A.x,y:A.y}];await IUe(i,{v:b.start,w:b.end,name:b.id},{...b,arrowTypeEnd:b.arrowTypeEnd,arrowTypeStart:b.arrowTypeStart,points:P,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",v,p),b.label&&(await zme(i,{...b,label:b.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:b.arrowTypeEnd,arrowTypeStart:b.arrowTypeStart,points:P,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),await MUe({...b,x:P[1].x,y:P[1].y},{originalPath:P}))}}}const e0=((RWe=(FWe=qt())==null?void 0:FWe.block)==null?void 0:RWe.padding)||8;function _cn(i,s){if(i===0||!Number.isInteger(i))throw new Error("Columns must be an integer !== 0.");if(s<0||!Number.isInteger(s))throw new Error("Position must be a non-negative integer."+s);if(i<0)return{px:s,py:0};if(i===1)return{px:0,py:s};const u=s%i,d=Math.floor(s/i);return{px:u,py:d}}const Acn=i=>{let s=0,u=0;for(const d of i.children){const{width:p,height:v,x:b,y}=d.size||{width:0,height:0,x:0,y:0};Xe.debug("getMaxChildSize abc95 child:",d.id,"width:",p,"height:",v,"x:",b,"y:",y,d.type),d.type!=="space"&&(p>s&&(s=p/(i.widthInColumns||1)),v>u&&(u=v))}return{width:s,height:u}};function gwe(i,s,u=0,d=0){var b,y,T,_,A,P,R,F,j,K,ee;Xe.debug("setBlockSizes abc95 (start)",i.id,(b=i==null?void 0:i.size)==null?void 0:b.x,"block width =",i==null?void 0:i.size,"sieblingWidth",u),(y=i==null?void 0:i.size)!=null&&y.width||(i.size={width:u,height:d,x:0,y:0});let p=0,v=0;if(((T=i.children)==null?void 0:T.length)>0){for(const de of i.children)gwe(de,s);const ie=Acn(i);p=ie.width,v=ie.height,Xe.debug("setBlockSizes abc95 maxWidth of",i.id,":s children is ",p,v);for(const de of i.children)de.size&&(Xe.debug(`abc95 Setting size of children of ${i.id} id=${de.id} ${p} ${v} ${de.size}`),de.size.width=p*(de.widthInColumns||1)+e0*((de.widthInColumns||1)-1),de.size.height=v,de.size.x=0,de.size.y=0,Xe.debug(`abc95 updating size of ${i.id} children child:${de.id} maxWidth:${p} maxHeight:${v}`));for(const de of i.children)gwe(de,s,p,v);const oe=i.columns||-1;let pe=0;for(const de of i.children)pe+=de.widthInColumns||1;let be=i.children.length;oe>0&&oe0?Math.min(i.children.length,oe):i.children.length;if(de>0){const X=(ne-de*e0-e0)/de;Xe.debug("abc95 (growing to fit) width",i.id,ne,(R=i.size)==null?void 0:R.width,X);for(const ge of i.children)ge.size&&(ge.size.width=X)}}i.size={width:ne,height:se,x:0,y:0}}Xe.debug("setBlockSizes abc94 (done)",i.id,(F=i==null?void 0:i.size)==null?void 0:F.x,(j=i==null?void 0:i.size)==null?void 0:j.width,(K=i==null?void 0:i.size)==null?void 0:K.y,(ee=i==null?void 0:i.size)==null?void 0:ee.height)}function PWe(i,s){var d,p,v,b,y,T,_,A,P,R,F,j,K,ee,ie,oe,pe;Xe.debug(`abc85 layout blocks (=>layoutBlocks) ${i.id} x: ${(d=i==null?void 0:i.size)==null?void 0:d.x} y: ${(p=i==null?void 0:i.size)==null?void 0:p.y} width: ${(v=i==null?void 0:i.size)==null?void 0:v.width}`);const u=i.columns||-1;if(Xe.debug("layoutBlocks columns abc95",i.id,"=>",u,i),i.children&&i.children.length>0){const be=((y=(b=i==null?void 0:i.children[0])==null?void 0:b.size)==null?void 0:y.width)||0,ae=i.children.length*be+(i.children.length-1)*e0;Xe.debug("widthOfChildren 88",ae,"posX");let ne=0;Xe.debug("abc91 block?.size?.x",i.id,(T=i==null?void 0:i.size)==null?void 0:T.x);let se=(_=i==null?void 0:i.size)!=null&&_.x?((A=i==null?void 0:i.size)==null?void 0:A.x)+(-((P=i==null?void 0:i.size)==null?void 0:P.width)/2||0):-e0,de=0;for(const X of i.children){const ge=i;if(!X.size)continue;const{width:W,height:xe}=X.size,{px:U,py:Fe}=_cn(u,ne);if(Fe!=de&&(de=Fe,se=(R=i==null?void 0:i.size)!=null&&R.x?((F=i==null?void 0:i.size)==null?void 0:F.x)+(-((j=i==null?void 0:i.size)==null?void 0:j.width)/2||0):-e0,Xe.debug("New row in layout for block",i.id," and child ",X.id,de)),Xe.debug(`abc89 layout blocks (child) id: ${X.id} Pos: ${ne} (px, py) ${U},${Fe} (${(K=ge==null?void 0:ge.size)==null?void 0:K.x},${(ee=ge==null?void 0:ge.size)==null?void 0:ee.y}) parent: ${ge.id} width: ${W}${e0}`),ge.size){const Pe=W/2;X.size.x=se+e0+Pe,Xe.debug(`abc91 layout blocks (calc) px, pyid:${X.id} startingPos=X${se} new startingPosX${X.size.x} ${Pe} padding=${e0} width=${W} halfWidth=${Pe} => x:${X.size.x} y:${X.size.y} ${X.widthInColumns} (width * (child?.w || 1)) / 2 ${W*((X==null?void 0:X.widthInColumns)||1)/2}`),se=X.size.x+Pe,X.size.y=ge.size.y-ge.size.height/2+Fe*(xe+e0)+xe/2+e0,Xe.debug(`abc88 layout blocks (calc) px, pyid:${X.id}startingPosX${se}${e0}${Pe}=>x:${X.size.x}y:${X.size.y}${X.widthInColumns}(width * (child?.w || 1)) / 2${W*((X==null?void 0:X.widthInColumns)||1)/2}`)}X.children&&PWe(X),ne+=(X==null?void 0:X.widthInColumns)||1,Xe.debug("abc88 columnsPos",X,ne)}}Xe.debug(`layout blocks (<==layoutBlocks) ${i.id} x: ${(ie=i==null?void 0:i.size)==null?void 0:ie.x} y: ${(oe=i==null?void 0:i.size)==null?void 0:oe.y} width: ${(pe=i==null?void 0:i.size)==null?void 0:pe.width}`)}function BWe(i,{minX:s,minY:u,maxX:d,maxY:p}={minX:0,minY:0,maxX:0,maxY:0}){if(i.size&&i.id!=="root"){const{x:v,y:b,width:y,height:T}=i.size;v-y/2d&&(d=v+y/2),b+T/2>p&&(p=b+T/2)}if(i.children)for(const v of i.children)({minX:s,minY:u,maxX:d,maxY:p}=BWe(v,{minX:s,minY:u,maxX:d,maxY:p}));return{minX:s,minY:u,maxX:d,maxY:p}}function Lcn(i){const s=i.getBlock("root");if(!s)return;gwe(s,i,0,0),PWe(s),Xe.debug("getBlocks",JSON.stringify(s,null,2));const{minX:u,minY:d,maxX:p,maxY:v}=BWe(s),b=v-d,y=p-u;return{x:u,y:d,width:y,height:b}}const Mcn=Object.freeze(Object.defineProperty({__proto__:null,diagram:{parser:ucn,db:ycn,renderer:{draw:async function(i,s,u,d){const{securityLevel:p,block:v}=Vh(),b=d.db;let y;p==="sandbox"&&(y=Ir("#i"+s));const T=Ir(p==="sandbox"?y.nodes()[0].contentDocument.body:"body"),_=p==="sandbox"?T.select(`[id="${s}"]`):Ir(`[id="${s}"]`);Sme(_,["point","circle","cross"],d.type,s);const P=b.getBlocks(),R=b.getBlocksFlat(),F=b.getEdges(),j=_.insert("g").attr("class","block");await Tcn(j,P,b);const K=Lcn(b);if(await Ccn(j,P,b),await Scn(j,F,R,b,s),K){const ee=K,ie=Math.max(1,Math.round(.125*(ee.width/ee.height))),oe=ee.height+ie+10,pe=ee.width+10,{useMaxWidth:be}=v;Ng(_,oe,pe,!!be),Xe.debug("Here Bounds",K,ee),_.attr("viewBox",`${ee.x-5} ${ee.y-5} ${ee.width+10} ${ee.height+10}`)}_F(zFe)},getClasses:function(i,s){return s.db.getClasses()}},styles:xcn}},Symbol.toStringTag,{value:"Module"}));return um}); diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 000000000..d011bad7e Binary files /dev/null and b/assets/favicon.png differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 000000000..1cf13b9f9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.6e7f53b1.min.js b/assets/javascripts/bundle.6e7f53b1.min.js new file mode 100644 index 000000000..c15d2b6fe --- /dev/null +++ b/assets/javascripts/bundle.6e7f53b1.min.js @@ -0,0 +1,3 @@ +"use strict";(()=>{var Bi=Object.create;var _r=Object.defineProperty;var Gi=Object.getOwnPropertyDescriptor;var Ji=Object.getOwnPropertyNames,Bt=Object.getOwnPropertySymbols,Xi=Object.getPrototypeOf,Ar=Object.prototype.hasOwnProperty,uo=Object.prototype.propertyIsEnumerable;var fo=(e,t,r)=>t in e?_r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,j=(e,t)=>{for(var r in t||(t={}))Ar.call(t,r)&&fo(e,r,t[r]);if(Bt)for(var r of Bt(t))uo.call(t,r)&&fo(e,r,t[r]);return e};var ho=(e,t)=>{var r={};for(var o in e)Ar.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Bt)for(var o of Bt(e))t.indexOf(o)<0&&uo.call(e,o)&&(r[o]=e[o]);return r};var Cr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Zi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ji(t))!Ar.call(e,n)&&n!==r&&_r(e,n,{get:()=>t[n],enumerable:!(o=Gi(t,n))||o.enumerable});return e};var Gt=(e,t,r)=>(r=e!=null?Bi(Xi(e)):{},Zi(t||!e||!e.__esModule?_r(r,"default",{value:e,enumerable:!0}):r,e));var bo=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var go=Cr((Hr,vo)=>{(function(e,t){typeof Hr=="object"&&typeof vo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Hr,function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(H){return!!(H&&H!==document&&H.nodeName!=="HTML"&&H.nodeName!=="BODY"&&"classList"in H&&"contains"in H.classList)}function c(H){var ft=H.type,Fe=H.tagName;return!!(Fe==="INPUT"&&s[ft]&&!H.readOnly||Fe==="TEXTAREA"&&!H.readOnly||H.isContentEditable)}function p(H){H.classList.contains("focus-visible")||(H.classList.add("focus-visible"),H.setAttribute("data-focus-visible-added",""))}function l(H){H.hasAttribute("data-focus-visible-added")&&(H.classList.remove("focus-visible"),H.removeAttribute("data-focus-visible-added"))}function f(H){H.metaKey||H.altKey||H.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(H){o=!1}function d(H){a(H.target)&&(o||c(H.target))&&p(H.target)}function g(H){a(H.target)&&(H.target.classList.contains("focus-visible")||H.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(H.target))}function L(H){document.visibilityState==="hidden"&&(n&&(o=!0),ee())}function ee(){document.addEventListener("mousemove",Z),document.addEventListener("mousedown",Z),document.addEventListener("mouseup",Z),document.addEventListener("pointermove",Z),document.addEventListener("pointerdown",Z),document.addEventListener("pointerup",Z),document.addEventListener("touchmove",Z),document.addEventListener("touchstart",Z),document.addEventListener("touchend",Z)}function ne(){document.removeEventListener("mousemove",Z),document.removeEventListener("mousedown",Z),document.removeEventListener("mouseup",Z),document.removeEventListener("pointermove",Z),document.removeEventListener("pointerdown",Z),document.removeEventListener("pointerup",Z),document.removeEventListener("touchmove",Z),document.removeEventListener("touchstart",Z),document.removeEventListener("touchend",Z)}function Z(H){H.target.nodeName&&H.target.nodeName.toLowerCase()==="html"||(o=!1,ne())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",L,!0),ee(),r.addEventListener("focus",d,!0),r.addEventListener("blur",g,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var io=Cr((Vt,no)=>{(function(t,r){typeof Vt=="object"&&typeof no=="object"?no.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Vt=="object"?Vt.ClipboardJS=r():t.ClipboardJS=r()})(Vt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Yi}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(z){try{return document.execCommand(z)}catch(C){return!1}}var d=function(C){var _=f()(C);return u("cut"),_},g=d;function L(z){var C=document.documentElement.getAttribute("dir")==="rtl",_=document.createElement("textarea");_.style.fontSize="12pt",_.style.border="0",_.style.padding="0",_.style.margin="0",_.style.position="absolute",_.style[C?"right":"left"]="-9999px";var D=window.pageYOffset||document.documentElement.scrollTop;return _.style.top="".concat(D,"px"),_.setAttribute("readonly",""),_.value=z,_}var ee=function(C,_){var D=L(C);_.container.appendChild(D);var N=f()(D);return u("copy"),D.remove(),N},ne=function(C){var _=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},D="";return typeof C=="string"?D=ee(C,_):C instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(C==null?void 0:C.type)?D=ee(C.value,_):(D=f()(C),u("copy")),D},Z=ne;function H(z){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?H=function(_){return typeof _}:H=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},H(z)}var ft=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},_=C.action,D=_===void 0?"copy":_,N=C.container,G=C.target,Ue=C.text;if(D!=="copy"&&D!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(G!==void 0)if(G&&H(G)==="object"&&G.nodeType===1){if(D==="copy"&&G.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(D==="cut"&&(G.hasAttribute("readonly")||G.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ue)return Z(Ue,{container:N});if(G)return D==="cut"?g(G):Z(G,{container:N})},Fe=ft;function R(z){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?R=function(_){return typeof _}:R=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},R(z)}function se(z,C){if(!(z instanceof C))throw new TypeError("Cannot call a class as a function")}function ce(z,C){for(var _=0;_0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof N.action=="function"?N.action:this.defaultAction,this.target=typeof N.target=="function"?N.target:this.defaultTarget,this.text=typeof N.text=="function"?N.text:this.defaultText,this.container=R(N.container)==="object"?N.container:document.body}},{key:"listenClick",value:function(N){var G=this;this.listener=p()(N,"click",function(Ue){return G.onClick(Ue)})}},{key:"onClick",value:function(N){var G=N.delegateTarget||N.currentTarget,Ue=this.action(G)||"copy",Yt=Fe({action:Ue,container:this.container,target:this.target(G),text:this.text(G)});this.emit(Yt?"success":"error",{action:Ue,text:Yt,trigger:G,clearSelection:function(){G&&G.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(N){return Mr("action",N)}},{key:"defaultTarget",value:function(N){var G=Mr("target",N);if(G)return document.querySelector(G)}},{key:"defaultText",value:function(N){return Mr("text",N)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(N){var G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return Z(N,G)}},{key:"cut",value:function(N){return g(N)}},{key:"isSupported",value:function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],G=typeof N=="string"?[N]:N,Ue=!!document.queryCommandSupported;return G.forEach(function(Yt){Ue=Ue&&!!document.queryCommandSupported(Yt)}),Ue}}]),_}(a()),Yi=Qi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,d,g){var L=p.apply(this,arguments);return l.addEventListener(u,L,g),{destroy:function(){l.removeEventListener(u,L,g)}}}function c(l,f,u,d,g){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(L){return a(L,f,u,d,g)}))}function p(l,f,u,d){return function(g){g.delegateTarget=s(g.target,f),g.delegateTarget&&d.call(l,g)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,d,g){if(!u&&!d&&!g)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(g))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,d,g);if(s.nodeList(u))return l(u,d,g);if(s.string(u))return f(u,d,g);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,d,g){return u.addEventListener(d,g),{destroy:function(){u.removeEventListener(d,g)}}}function l(u,d,g){return Array.prototype.forEach.call(u,function(L){L.addEventListener(d,g)}),{destroy:function(){Array.prototype.forEach.call(u,function(L){L.removeEventListener(d,g)})}}}function f(u,d,g){return a(document.body,u,d,g)}o.exports=c},817:function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c{"use strict";var fs=/["'&<>]/;di.exports=us;function us(e){var t=""+e,r=fs.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function q(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function B(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||a(u,d)})})}function a(u,d){try{c(o[u](d))}catch(g){f(i[0][3],g)}}function c(u){u.value instanceof ut?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){a("next",u)}function l(u){a("throw",u)}function f(u,d){u(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function Eo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Oe=="function"?Oe(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function P(e){return typeof e=="function"}function xt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Xt=xt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Xe(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var ze=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Oe(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(L){t={error:L}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(P(l))try{l()}catch(L){i=L instanceof Xt?L.errors:[L]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=Oe(f),d=u.next();!d.done;d=u.next()){var g=d.value;try{wo(g)}catch(L){i=i!=null?i:[],L instanceof Xt?i=B(B([],q(i)),q(L.errors)):i.push(L)}}}catch(L){o={error:L}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Xt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)wo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Xe(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Xe(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var $r=ze.EMPTY;function Zt(e){return e instanceof ze||e&&"closed"in e&&P(e.remove)&&P(e.add)&&P(e.unsubscribe)}function wo(e){P(e)?e():e.unsubscribe()}var We={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var yt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?$r:(this.currentObservers=null,a.push(r),new ze(function(){o.currentObservers=null,Xe(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new I;return r.source=this,r},t.create=function(r,o){return new Co(r,o)},t}(I);var Co=function(e){ie(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:$r},t}(T);var jr=function(e){ie(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(T);var Pt={now:function(){return(Pt.delegate||Date).now()},delegate:void 0};var It=function(e){ie(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=Pt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(St);var $o=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(Ot);var Dr=new $o(ko);var Ro=function(e){ie(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=Tt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(Tt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(St);var Po=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(Ot);var ge=new Po(Ro);var x=new I(function(e){return e.complete()});function rr(e){return e&&P(e.schedule)}function Nr(e){return e[e.length-1]}function ct(e){return P(Nr(e))?e.pop():void 0}function Ie(e){return rr(Nr(e))?e.pop():void 0}function or(e,t){return typeof Nr(e)=="number"?e.pop():t}var Lt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function nr(e){return P(e==null?void 0:e.then)}function ir(e){return P(e[wt])}function ar(e){return Symbol.asyncIterator&&P(e==null?void 0:e[Symbol.asyncIterator])}function sr(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function ca(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var cr=ca();function pr(e){return P(e==null?void 0:e[cr])}function lr(e){return yo(this,arguments,function(){var r,o,n,i;return Jt(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,ut(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,ut(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,ut(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function mr(e){return P(e==null?void 0:e.getReader)}function U(e){if(e instanceof I)return e;if(e!=null){if(ir(e))return pa(e);if(Lt(e))return la(e);if(nr(e))return ma(e);if(ar(e))return Io(e);if(pr(e))return fa(e);if(mr(e))return ua(e)}throw sr(e)}function pa(e){return new I(function(t){var r=e[wt]();if(P(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function la(e){return new I(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?v(function(n,i){return e(n,i,o)}):be,Ee(1),r?rt(t):Zo(function(){return new ur}))}}function Yr(e){return e<=0?function(){return x}:E(function(t,r){var o=[];t.subscribe(w(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new T}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,d=0,g=!1,L=!1,ee=function(){f==null||f.unsubscribe(),f=void 0},ne=function(){ee(),l=u=void 0,g=L=!1},Z=function(){var H=l;ne(),H==null||H.unsubscribe()};return E(function(H,ft){d++,!L&&!g&&ee();var Fe=u=u!=null?u:r();ft.add(function(){d--,d===0&&!L&&!g&&(f=Br(Z,c))}),Fe.subscribe(ft),!l&&d>0&&(l=new ht({next:function(R){return Fe.next(R)},error:function(R){L=!0,ee(),f=Br(ne,n,R),Fe.error(R)},complete:function(){g=!0,ee(),f=Br(ne,s),Fe.complete()}}),U(H).subscribe(l))})(p)}}function Br(e,t){for(var r=[],o=2;oe.next(document)),e}function M(e,t=document){return Array.from(t.querySelectorAll(e))}function F(e,t=document){let r=ue(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ue(e,t=document){return t.querySelector(e)||void 0}function Ve(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var Ha=O(h(document.body,"focusin"),h(document.body,"focusout")).pipe(Ae(1),K(void 0),m(()=>Ve()||document.body),X(1));function Ke(e){return Ha.pipe(m(t=>e.contains(t)),Y())}function nt(e,t){return k(()=>O(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?jt(r=>ke(+!r*t)):be,K(e.matches(":hover"))))}function nn(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)nn(e,r)}function y(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)nn(o,n);return o}function br(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function At(e){let t=y("script",{src:e});return k(()=>(document.head.appendChild(t),O(h(t,"load"),h(t,"error").pipe(b(()=>Vr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),A(()=>document.head.removeChild(t)),Ee(1))))}var an=new T,ka=k(()=>typeof ResizeObserver=="undefined"?At("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>an.next(t)))),b(e=>O(et,$(e)).pipe(A(()=>e.disconnect()))),X(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Le(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return ka.pipe(S(r=>r.observe(t)),b(r=>an.pipe(v(o=>o.target===t),A(()=>r.unobserve(t)))),m(()=>de(e)),K(de(e)))}function Ct(e){return{width:e.scrollWidth,height:e.scrollHeight}}function vr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function sn(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Qe(e){return{x:e.offsetLeft,y:e.offsetTop}}function cn(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function pn(e){return O(h(window,"load"),h(window,"resize")).pipe($e(0,ge),m(()=>Qe(e)),K(Qe(e)))}function gr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ye(e){return O(h(e,"scroll"),h(window,"scroll"),h(window,"resize")).pipe($e(0,ge),m(()=>gr(e)),K(gr(e)))}var ln=new T,$a=k(()=>$(new IntersectionObserver(e=>{for(let t of e)ln.next(t)},{threshold:0}))).pipe(b(e=>O(et,$(e)).pipe(A(()=>e.disconnect()))),X(1));function lt(e){return $a.pipe(S(t=>t.observe(e)),b(t=>ln.pipe(v(({target:r})=>r===e),A(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function mn(e,t=16){return Ye(e).pipe(m(({y:r})=>{let o=de(e),n=Ct(e);return r>=n.height-o.height-t}),Y())}var xr={drawer:F("[data-md-toggle=drawer]"),search:F("[data-md-toggle=search]")};function fn(e){return xr[e].checked}function it(e,t){xr[e].checked!==t&&xr[e].click()}function Be(e){let t=xr[e];return h(t,"change").pipe(m(()=>t.checked),K(t.checked))}function Ra(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Pa(){return O(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(K(!1))}function un(){let e=h(window,"keydown").pipe(v(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:fn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),v(({mode:t,type:r})=>{if(t==="global"){let o=Ve();if(typeof o!="undefined")return!Ra(o,r)}return!0}),le());return Pa().pipe(b(t=>t?x:e))}function we(){return new URL(location.href)}function at(e,t=!1){if(Q("navigation.instant")&&!t){let r=y("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function dn(){return new T}function hn(){return location.hash.slice(1)}function bn(e){let t=y("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Zr(e){return O(h(window,"hashchange"),e).pipe(m(hn),K(hn()),v(t=>t.length>0),X(1))}function vn(e){return Zr(e).pipe(m(t=>ue(`[id="${t}"]`)),v(t=>typeof t!="undefined"))}function Wt(e){let t=matchMedia(e);return dr(r=>t.addListener(()=>r(t.matches))).pipe(K(t.matches))}function gn(){let e=matchMedia("print");return O(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(K(e.matches))}function eo(e,t){return e.pipe(b(r=>r?t():x))}function to(e,t){return new I(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function Ge(e,t){return to(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),X(1))}function yr(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),X(1))}function xn(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),X(1))}function yn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function En(){return O(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(yn),K(yn()))}function wn(){return{width:innerWidth,height:innerHeight}}function Tn(){return h(window,"resize",{passive:!0}).pipe(m(wn),K(wn()))}function Sn(){return V([En(),Tn()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function Er(e,{viewport$:t,header$:r}){let o=t.pipe(oe("size")),n=V([o,r]).pipe(m(()=>Qe(e)));return V([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function Ia(e){return h(e,"message",t=>t.data)}function Fa(e){let t=new T;return t.subscribe(r=>e.postMessage(r)),t}function On(e,t=new Worker(e)){let r=Ia(t),o=Fa(t),n=new T;n.subscribe(o);let i=o.pipe(re(),ae(!0));return n.pipe(re(),Ne(r.pipe(W(i))),le())}var ja=F("#__config"),Ht=JSON.parse(ja.textContent);Ht.base=`${new URL(Ht.base,we())}`;function Te(){return Ht}function Q(e){return Ht.features.includes(e)}function Me(e,t){return typeof t!="undefined"?Ht.translations[e].replace("#",t.toString()):Ht.translations[e]}function Ce(e,t=document){return F(`[data-md-component=${e}]`,t)}function me(e,t=document){return M(`[data-md-component=${e}]`,t)}function Ua(e){let t=F(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>F(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function Ln(e){if(!Q("announce.dismiss")||!e.childElementCount)return x;if(!e.hidden){let t=F(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return k(()=>{let t=new T;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Ua(e).pipe(S(r=>t.next(r)),A(()=>t.complete()),m(r=>j({ref:e},r)))})}function Wa(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function Mn(e,t){let r=new T;return r.subscribe(({hidden:o})=>{e.hidden=o}),Wa(e,t).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))}function Dt(e,t){return t==="inline"?y("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},y("div",{class:"md-tooltip__inner md-typeset"})):y("div",{class:"md-tooltip",id:e,role:"tooltip"},y("div",{class:"md-tooltip__inner md-typeset"}))}function wr(...e){return y("div",{class:"md-tooltip2",role:"dialog"},y("div",{class:"md-tooltip2__inner md-typeset"},e))}function _n(...e){return y("div",{class:"md-tooltip2",role:"tooltip"},y("div",{class:"md-tooltip2__inner md-typeset"},e))}function An(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return y("aside",{class:"md-annotation",tabIndex:0},Dt(t),y("a",{href:r,class:"md-annotation__index",tabIndex:-1},y("span",{"data-md-annotation-id":e})))}else return y("aside",{class:"md-annotation",tabIndex:0},Dt(t),y("span",{class:"md-annotation__index",tabIndex:-1},y("span",{"data-md-annotation-id":e})))}function Cn(e){return y("button",{class:"md-code__button",title:Me("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function Hn(){return y("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function kn(){return y("nav",{class:"md-code__nav"})}function ro(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,y("del",null,p)," "],[]).slice(0,-1),i=Te(),s=new URL(e.location,i.base);Q("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=Te();return y("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},y("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&y("div",{class:"md-search-result__icon md-icon"}),r>0&&y("h1",null,e.title),r<=0&&y("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return y("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&y("p",{class:"md-search-result__terms"},Me("search.result.term.missing"),": ",...n)))}function $n(e){let t=e[0].score,r=[...e],o=Te(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scorero(l,1)),...c.length?[y("details",{class:"md-search-result__more"},y("summary",{tabIndex:-1},y("div",null,c.length>0&&c.length===1?Me("search.result.more.one"):Me("search.result.more.other",c.length))),...c.map(l=>ro(l,1)))]:[]];return y("li",{class:"md-search-result__item"},p)}function Rn(e){return y("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>y("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?br(r):r)))}function oo(e){let t=`tabbed-control tabbed-control--${e}`;return y("div",{class:t,hidden:!0},y("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function Pn(e){return y("div",{class:"md-typeset__scrollwrap"},y("div",{class:"md-typeset__table"},e))}function Da(e){var o;let t=Te(),r=new URL(`../${e.version}/`,t.base);return y("li",{class:"md-version__item"},y("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&y("span",{class:"md-version__alias"},e.aliases[0])))}function In(e,t){var o;let r=Te();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),y("div",{class:"md-version"},y("button",{class:"md-version__current","aria-label":Me("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&y("span",{class:"md-version__alias"},t.aliases[0])),y("ul",{class:"md-version__list"},e.map(Da)))}var Na=0;function Va(e,t=250){let r=V([Ke(e),nt(e,t)]).pipe(m(([n,i])=>n||i),Y()),o=k(()=>sn(e)).pipe(J(Ye),gt(1),m(()=>cn(e)));return r.pipe(Re(n=>n),b(()=>V([r,o])),m(([n,i])=>({active:n,offset:i})),le())}function Nt(e,t,r=250){let{content$:o,viewport$:n}=t,i=`__tooltip2_${Na++}`;return k(()=>{let s=new T,a=new jr(!1);s.pipe(re(),ae(!1)).subscribe(a);let c=a.pipe(jt(l=>ke(+!l*250,Dr)),Y(),b(l=>l?o:x),S(l=>l.id=i),le());V([s.pipe(m(({active:l})=>l)),c.pipe(b(l=>nt(l,250)),K(!1))]).pipe(m(l=>l.some(f=>f))).subscribe(a);let p=a.pipe(v(l=>l),te(c,n),m(([l,f,{size:u}])=>{let d=e.getBoundingClientRect(),g=d.width/2;if(f.role==="tooltip")return{x:g,y:8+d.height};if(d.y>=u.height/2){let{height:L}=de(f);return{x:g,y:-16-L}}else return{x:g,y:16+d.height}}));return V([c,s,p]).subscribe(([l,{offset:f},u])=>{l.style.setProperty("--md-tooltip-host-x",`${f.x}px`),l.style.setProperty("--md-tooltip-host-y",`${f.y}px`),l.style.setProperty("--md-tooltip-x",`${u.x}px`),l.style.setProperty("--md-tooltip-y",`${u.y}px`),l.classList.toggle("md-tooltip2--top",u.y<0),l.classList.toggle("md-tooltip2--bottom",u.y>=0)}),a.pipe(v(l=>l),te(c,(l,f)=>f),v(l=>l.role==="tooltip")).subscribe(l=>{let f=de(F(":scope > *",l));l.style.setProperty("--md-tooltip-width",`${f.width}px`),l.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(Y(),xe(ge),te(c)).subscribe(([l,f])=>{f.classList.toggle("md-tooltip2--active",l)}),V([a.pipe(v(l=>l)),c]).subscribe(([l,f])=>{f.role==="dialog"?(e.setAttribute("aria-controls",i),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",i)}),a.pipe(v(l=>!l)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),Va(e,r).pipe(S(l=>s.next(l)),A(()=>s.complete()),m(l=>j({ref:e},l)))})}function Je(e,{viewport$:t},r=document.body){return Nt(e,{content$:new I(o=>{let n=e.title,i=_n(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t},0)}function za(e,t){let r=k(()=>V([pn(e),Ye(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=de(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return Ke(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),Ee(+!o||1/0))))}function Fn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return k(()=>{let i=new T,s=i.pipe(re(),ae(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),lt(e).pipe(W(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),O(i.pipe(v(({active:a})=>a)),i.pipe(Ae(250),v(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe($e(16,ge)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(gt(125,ge),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(W(s),v(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),h(n,"mousedown").pipe(W(s),te(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Ve())==null||p.blur()}}),r.pipe(W(s),v(a=>a===o),ot(125)).subscribe(()=>e.focus()),za(e,t).pipe(S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))})}function qa(e){let t=Te();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(typeof t.annotate!="undefined"){let o=e.closest("[class|=language]");if(o)for(let n of Array.from(o.classList)){if(!n.startsWith("language-"))continue;let[,i]=n.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return M(r.join(", "),e)}function Ka(e){let t=[];for(let r of qa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function jn(e,t){t.append(...Array.from(e.childNodes))}function Tr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of Ka(t)){let[,c]=a.textContent.match(/\((\d+)\)/);ue(`:scope > li:nth-child(${c})`,e)&&(s.set(c,An(c,i)),a.replaceWith(s.get(c)))}return s.size===0?x:k(()=>{let a=new T,c=a.pipe(re(),ae(!0)),p=[];for(let[l,f]of s)p.push([F(".md-typeset",f),F(`:scope > li:nth-child(${l})`,e)]);return o.pipe(W(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?jn(f,u):jn(u,f)}),O(...[...s].map(([,l])=>Fn(l,t,{target$:r}))).pipe(A(()=>a.complete()),le())})}function Un(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Un(t)}}function Wn(e,t){return k(()=>{let r=Un(e);return typeof r!="undefined"?Tr(r,e,t):x})}var Nn=Gt(io());var Qa=0,Dn=O(h(window,"keydown").pipe(m(()=>!0)),O(h(window,"keyup"),h(window,"contextmenu")).pipe(m(()=>!1))).pipe(K(!1),X(1));function Vn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Vn(t)}}function Ya(e){return Le(e).pipe(m(({width:t})=>({scrollable:Ct(e).width>t})),oe("scrollable"))}function zn(e,t){let{matches:r}=matchMedia("(hover)"),o=k(()=>{let n=new T,i=n.pipe(Yr(1));n.subscribe(({scrollable:d})=>{d&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[],a=e.closest("pre"),c=a.closest("[id]"),p=c?c.id:Qa++;a.id=`__code_${p}`;let l=[],f=e.closest(".highlight");if(f instanceof HTMLElement){let d=Vn(f);if(typeof d!="undefined"&&(f.classList.contains("annotate")||Q("content.code.annotate"))){let g=Tr(d,e,t);l.push(Le(f).pipe(W(i),m(({width:L,height:ee})=>L&&ee),Y(),b(L=>L?g:x)))}}let u=M(":scope > span[id]",e);if(u.length&&(e.classList.add("md-code__content"),e.closest(".select")||Q("content.code.select")&&!e.closest(".no-select"))){let d=+u[0].id.split("-").pop(),g=Hn();s.push(g),Q("content.tooltips")&&l.push(Je(g,{viewport$}));let L=h(g,"click").pipe(Ut(R=>!R,!1),S(()=>g.blur()),le());L.subscribe(R=>{g.classList.toggle("md-code__button--active",R)});let ee=fe(u).pipe(J(R=>nt(R).pipe(m(se=>[R,se]))));L.pipe(b(R=>R?ee:x)).subscribe(([R,se])=>{let ce=ue(".hll.select",R);if(ce&&!se)ce.replaceWith(...Array.from(ce.childNodes));else if(!ce&&se){let he=document.createElement("span");he.className="hll select",he.append(...Array.from(R.childNodes).slice(1)),R.append(he)}});let ne=fe(u).pipe(J(R=>h(R,"mousedown").pipe(S(se=>se.preventDefault()),m(()=>R)))),Z=L.pipe(b(R=>R?ne:x),te(Dn),m(([R,se])=>{var he;let ce=u.indexOf(R)+d;if(se===!1)return[ce,ce];{let Se=M(".hll",e).map(je=>u.indexOf(je.parentElement)+d);return(he=window.getSelection())==null||he.removeAllRanges(),[Math.min(ce,...Se),Math.max(ce,...Se)]}})),H=Zr(x).pipe(v(R=>R.startsWith(`__codelineno-${p}-`)));H.subscribe(R=>{let[,,se]=R.split("-"),ce=se.split(":").map(Se=>+Se-d+1);ce.length===1&&ce.push(ce[0]);for(let Se of M(".hll:not(.select)",e))Se.replaceWith(...Array.from(Se.childNodes));let he=u.slice(ce[0]-1,ce[1]);for(let Se of he){let je=document.createElement("span");je.className="hll",je.append(...Array.from(Se.childNodes).slice(1)),Se.append(je)}}),H.pipe(Ee(1),xe(pe)).subscribe(R=>{if(R.includes(":")){let se=document.getElementById(R.split(":")[0]);se&&setTimeout(()=>{let ce=se,he=-64;for(;ce!==document.body;)he+=ce.offsetTop,ce=ce.offsetParent;window.scrollTo({top:he})},1)}});let Fe=fe(M('a[href^="#__codelineno"]',f)).pipe(J(R=>h(R,"click").pipe(S(se=>se.preventDefault()),m(()=>R)))).pipe(W(i),te(Dn),m(([R,se])=>{let he=+F(`[id="${R.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(se===!1)return[he,he];{let Se=M(".hll",e).map(je=>+je.parentElement.id.split("-").pop());return[Math.min(he,...Se),Math.max(he,...Se)]}}));O(Z,Fe).subscribe(R=>{let se=`#__codelineno-${p}-`;R[0]===R[1]?se+=R[0]:se+=`${R[0]}:${R[1]}`,history.replaceState({},"",se),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+se,oldURL:window.location.href}))})}if(Nn.default.isSupported()&&(e.closest(".copy")||Q("content.code.copy")&&!e.closest(".no-copy"))){let d=Cn(a.id);s.push(d),Q("content.tooltips")&&l.push(Je(d,{viewport$}))}if(s.length){let d=kn();d.append(...s),a.insertBefore(d,e)}return Ya(e).pipe(S(d=>n.next(d)),A(()=>n.complete()),m(d=>j({ref:e},d)),Ne(O(...l).pipe(W(i))))});return Q("content.lazy")?lt(e).pipe(v(n=>n),Ee(1),b(()=>o)):o}function Ba(e,{target$:t,print$:r}){let o=!0;return O(t.pipe(m(n=>n.closest("details:not([open])")),v(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(v(n=>n||!o),S(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function qn(e,t){return k(()=>{let r=new T;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Ba(e,t).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Ga(e){let t=document.createElement("h3");t.innerHTML=e.innerHTML;let r=[t],o=e.nextElementSibling;for(;o&&!(o instanceof HTMLHeadingElement);)r.push(o),o=o.nextElementSibling;return r}function Ja(e,t){for(let r of M("[href], [src]",e))for(let o of["href","src"]){let n=r.getAttribute(o);if(n&&!/^(?:[a-z]+:)?\/\//i.test(n)){r[o]=new URL(r.getAttribute(o),t).toString();break}}return $(e)}function Kn(e,t){let{sitemap$:r}=t;if(!(e instanceof HTMLAnchorElement))return x;if(!(Q("navigation.instant.preview")||e.hasAttribute("data-preview")))return x;let o=V([Ke(e),nt(e)]).pipe(m(([i,s])=>i||s),Y(),v(i=>i));return bt([r,o]).pipe(b(([i])=>{let s=new URL(e.href);return s.search=s.hash="",i.has(`${s}`)?$(s):x}),b(i=>yr(i).pipe(b(s=>Ja(s,i)))),b(i=>{let s=e.hash?`article [id="${e.hash.slice(1)}"]`:"article h1",a=ue(s,i);return typeof a=="undefined"?x:$(Ga(a))})).pipe(b(i=>{let s=new I(a=>{let c=wr(...i);return a.next(c),document.body.append(c),()=>c.remove()});return Nt(e,j({content$:s},t))}))}var Qn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var ao,Za=0;function es(){return typeof mermaid=="undefined"||mermaid instanceof Element?At("https://wpbrowser.wptestkit.dev/assets/external/unpkg.com/mermaid@10/dist/mermaid.min.js"):$(void 0)}function Yn(e){return e.classList.remove("mermaid"),ao||(ao=es().pipe(S(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Qn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),X(1))),ao.subscribe(()=>bo(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${Za++}`,r=y("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),ao.pipe(m(()=>({ref:e})))}var Bn=y("table");function Gn(e){return e.replaceWith(Bn),Bn.replaceWith(Pn(e)),$({ref:e})}function ts(e){let t=e.find(r=>r.checked)||e[0];return O(...e.map(r=>h(r,"change").pipe(m(()=>F(`label[for="${r.id}"]`))))).pipe(K(F(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Jn(e,{viewport$:t,target$:r}){let o=F(".tabbed-labels",e),n=M(":scope > input",e),i=oo("prev");e.append(i);let s=oo("next");return e.append(s),k(()=>{let a=new T,c=a.pipe(re(),ae(!0));V([a,Le(e),lt(e)]).pipe(W(c),$e(1,ge)).subscribe({next([{active:p},l]){let f=Qe(p),{width:u}=de(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=gr(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),V([Ye(o),Le(o)]).pipe(W(c)).subscribe(([p,l])=>{let f=Ct(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),O(h(i,"click").pipe(m(()=>-1)),h(s,"click").pipe(m(()=>1))).pipe(W(c)).subscribe(p=>{let{width:l}=de(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(W(c),v(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=F(`label[for="${p.id}"]`);l.replaceChildren(y("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(W(c),v(f=>!(f.metaKey||f.ctrlKey)),S(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return Q("content.tabs.link")&&a.pipe(Pe(1),te(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let g of M("[data-tabs]"))for(let L of M(":scope > input",g)){let ee=F(`label[for="${L.id}"]`);if(ee!==p&&ee.innerText.trim()===f){ee.setAttribute("data-md-switching",""),L.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),a.pipe(W(c)).subscribe(()=>{for(let p of M("audio, video",e))p.pause()}),ts(n).pipe(S(p=>a.next(p)),A(()=>a.complete()),m(p=>j({ref:e},p)))}).pipe(Ze(pe))}function Xn(e,t){let{viewport$:r,target$:o,print$:n}=t;return O(...M(".annotate:not(.highlight)",e).map(i=>Wn(i,{target$:o,print$:n})),...M("pre:not(.mermaid) > code",e).map(i=>zn(i,{target$:o,print$:n})),...M("a:not([title])",e).map(i=>Kn(i,t)),...M("pre.mermaid",e).map(i=>Yn(i)),...M("table:not([class])",e).map(i=>Gn(i)),...M("details",e).map(i=>qn(i,{target$:o,print$:n})),...M("[data-tabs]",e).map(i=>Jn(i,{viewport$:r,target$:o})),...M("[title]",e).filter(()=>Q("content.tooltips")).map(i=>Je(i,{viewport$:r})),...M(".footnote-ref",e).filter(()=>Q("content.footnote.tooltips")).map(i=>Nt(i,{content$:new I(s=>{let a=new URL(i.href).hash.slice(1),c=Array.from(document.getElementById(a).cloneNode(!0).children),p=wr(...c);return s.next(p),document.body.append(p),()=>p.remove()}),viewport$:r})))}function rs(e,{alert$:t}){return t.pipe(b(r=>O($(!0),$(!1).pipe(ot(2e3))).pipe(m(o=>({message:r,active:o})))))}function Zn(e,t){let r=F(".md-typeset",e);return k(()=>{let o=new T;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),rs(e,t).pipe(S(n=>o.next(n)),A(()=>o.complete()),m(n=>j({ref:e},n)))})}var os=0;function ns(e,t){document.body.append(e);let{width:r}=de(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=vr(t),n=typeof o!="undefined"?Ye(o):$({x:0,y:0}),i=O(Ke(t),nt(t)).pipe(Y());return V([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Qe(t),l=de(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function ei(e){let t=e.title;if(!t.length)return x;let r=`__tooltip_${os++}`,o=Dt(r,"inline"),n=F(".md-typeset",o);return n.innerHTML=t,k(()=>{let i=new T;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),O(i.pipe(v(({active:s})=>s)),i.pipe(Ae(250),v(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe($e(16,ge)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(gt(125,ge),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),ns(o,e).pipe(S(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))}).pipe(Ze(pe))}function is({viewport$:e}){if(!Q("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),tt(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=Be("search");return V([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),b(n=>n?r:$(!1)),K(!1))}function ti(e,t){return k(()=>V([Le(e),is(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),X(1))}function ri(e,{header$:t,main$:r}){return k(()=>{let o=new T,n=o.pipe(re(),ae(!0));o.pipe(oe("active"),De(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=fe(M("[title]",e)).pipe(v(()=>Q("content.tooltips")),J(s=>ei(s)));return r.subscribe(o),t.pipe(W(n),m(s=>j({ref:e},s)),Ne(i.pipe(W(n))))})}function as(e,{viewport$:t,header$:r}){return Er(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=de(e);return{active:o>=n}}),oe("active"))}function oi(e,t){return k(()=>{let r=new T;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=ue(".md-content h1");return typeof o=="undefined"?x:as(o,t).pipe(S(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))})}function ni(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(b(()=>Le(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),oe("bottom"))));return V([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Y((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function ss(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(J(o=>h(o,"change").pipe(m(()=>o))),K(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),X(1))}function ii(e){let t=M("input",e),r=y("meta",{name:"theme-color"});document.head.appendChild(r);let o=y("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Wt("(prefers-color-scheme: light)");return k(()=>{let i=new T;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;as.key==="Enter"),te(i,(s,a)=>a)).subscribe(({index:s})=>{s=(s+1)%t.length,t[s].click(),t[s].focus()}),i.pipe(m(()=>{let s=Ce("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(xe(pe)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),ss(t).pipe(W(n.pipe(Pe(1))),vt(),S(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))})}function ai(e,{progress$:t}){return k(()=>{let r=new T;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(S(o=>r.next({value:o})),A(()=>r.complete()),m(o=>({ref:e,value:o})))})}function si(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function cs(e,t){let r=new Map;for(let o of M("url",e)){let n=F("loc",o),i=[si(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of M("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(si(new URL(a),t))}}return r}function kt(e){return xn(new URL("sitemap.xml",e)).pipe(m(t=>cs(t,new URL(e))),ye(()=>$(new Map)),le())}function ci({document$:e}){let t=new Map;e.pipe(b(()=>M("link[rel=alternate]")),m(r=>new URL(r.href)),v(r=>!t.has(r.toString())),J(r=>kt(r).pipe(m(o=>[r,o]),ye(()=>x)))).subscribe(([r,o])=>{t.set(r.toString().replace(/\/$/,""),o)}),h(document.body,"click").pipe(v(r=>!r.metaKey&&!r.ctrlKey),b(r=>{if(r.target instanceof Element){let o=r.target.closest("a");if(o&&!o.target){let n=[...t].find(([f])=>o.href.startsWith(`${f}/`));if(typeof n=="undefined")return x;let[i,s]=n,a=we();if(a.href.startsWith(i))return x;let c=Te(),p=a.href.replace(c.base,"");p=`${i}/${p}`;let l=s.has(p.split("#")[0])?new URL(p,c.base):new URL(i);return r.preventDefault(),$(l)}}return x})).subscribe(r=>at(r,!0))}var so=Gt(io());function ps(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function pi({alert$:e}){so.default.isSupported()&&new I(t=>{new so.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||ps(F(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(S(t=>{t.trigger.focus()}),m(()=>Me("clipboard.copied"))).subscribe(e)}function li(e,t){if(!(e.target instanceof Element))return x;let r=e.target.closest("a");if(r===null)return x;if(r.target||e.metaKey||e.ctrlKey)return x;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(r)):x}function mi(e){let t=new Map;for(let r of M(":scope > *",e.head))t.set(r.outerHTML,r);return t}function fi(e){for(let t of M("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function ls(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...Q("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=ue(o),i=ue(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=mi(document);for(let[o,n]of mi(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Ce("container");return qe(M("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new I(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),x}),re(),ae(document))}function ui({sitemap$:e,location$:t,viewport$:r,progress$:o}){if(location.protocol==="file:")return x;$(document).subscribe(fi);let n=h(document.body,"click").pipe(De(e),b(([a,c])=>li(a,c)),m(({href:a})=>new URL(a)),le()),i=h(window,"popstate").pipe(m(we),le());n.pipe(te(r)).subscribe(([a,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",a)}),O(n,i).subscribe(t);let s=t.pipe(oe("pathname"),b(a=>yr(a,{progress$:o}).pipe(ye(()=>(at(a,!0),x)))),b(fi),b(ls),le());return O(s.pipe(te(t,(a,c)=>c)),s.pipe(b(()=>t),oe("pathname"),b(()=>t),oe("hash")),t.pipe(Y((a,c)=>a.pathname===c.pathname&&a.hash===c.hash),b(()=>n),S(()=>history.back()))).subscribe(a=>{var c,p;history.state!==null||!a.hash?window.scrollTo(0,(p=(c=history.state)==null?void 0:c.y)!=null?p:0):(history.scrollRestoration="auto",bn(a.hash),history.scrollRestoration="manual")}),t.subscribe(()=>{history.scrollRestoration="manual"}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),r.pipe(oe("offset"),Ae(100)).subscribe(({offset:a})=>{history.replaceState(a,"")}),Q("navigation.instant.prefetch")&&O(h(document.body,"mousemove"),h(document.body,"focusin")).pipe(De(e),b(([a,c])=>li(a,c)),Ae(25),Qr(({href:a})=>a),hr(a=>{let c=document.createElement("link");return c.rel="prefetch",c.href=a.toString(),document.head.appendChild(c),h(c,"load").pipe(m(()=>c),Ee(1))})).subscribe(a=>a.remove()),s}var bi=Gt(hi());function vi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,bi.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function zt(e){return e.type===1}function Sr(e){return e.type===3}function gi(e,t){let r=On(e);return O($(location.protocol!=="file:"),Be("search")).pipe(Re(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:Q("search.suggest")}}})),r}function xi({document$:e}){let t=Te(),r=Ge(new URL("../versions.json",t.base)).pipe(ye(()=>x)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>h(document.body,"click").pipe(v(i=>!i.metaKey&&!i.ctrlKey),te(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?x:(i.preventDefault(),$(c))}}return x}),b(i=>kt(new URL(i)).pipe(m(s=>{let c=we().href.replace(t.base,i);return s.has(c.split("#")[0])?new URL(c):new URL(i)})))))).subscribe(n=>at(n,!0)),V([r,o]).subscribe(([n,i])=>{F(".md-header__topic").appendChild(In(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of me("outdated"))a.hidden=!1})}function hs(e,{worker$:t}){let{searchParams:r}=we();r.has("q")&&(it("search",!0),e.value=r.get("q"),e.focus(),Be("search").pipe(Re(i=>!i)).subscribe(()=>{let i=we();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Ke(e),n=O(t.pipe(Re(zt)),h(e,"keyup"),o).pipe(m(()=>e.value),Y());return V([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),X(1))}function yi(e,{worker$:t}){let r=new T,o=r.pipe(re(),ae(!0));V([t.pipe(Re(zt)),r],(i,s)=>s).pipe(oe("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(oe("focus")).subscribe(({focus:i})=>{i&&it("search",i)}),h(e.form,"reset").pipe(W(o)).subscribe(()=>e.focus());let n=F("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),hs(e,{worker$:t}).pipe(S(i=>r.next(i)),A(()=>r.complete()),m(i=>j({ref:e},i)),X(1))}function Ei(e,{worker$:t,query$:r}){let o=new T,n=mn(e.parentElement).pipe(v(Boolean)),i=e.parentElement,s=F(":scope > :first-child",e),a=F(":scope > :last-child",e);Be("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(te(r),Gr(t.pipe(Re(zt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?Me("search.result.none"):Me("search.result.placeholder");break;case 1:s.textContent=Me("search.result.one");break;default:let u=br(l.length);s.textContent=Me("search.result.other",u)}});let c=o.pipe(S(()=>a.innerHTML=""),b(({items:l})=>O($(...l.slice(0,10)),$(...l.slice(10)).pipe(tt(4),Xr(n),b(([f])=>f)))),m($n),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(J(l=>{let f=ue("details",l);return typeof f=="undefined"?x:h(f,"toggle").pipe(W(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(v(Sr),m(({data:l})=>l)).pipe(S(l=>o.next(l)),A(()=>o.complete()),m(l=>j({ref:e},l)))}function bs(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=we();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function wi(e,t){let r=new T,o=r.pipe(re(),ae(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(W(o)).subscribe(n=>n.preventDefault()),bs(e,t).pipe(S(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))}function Ti(e,{worker$:t,keyboard$:r}){let o=new T,n=Ce("search-query"),i=O(h(n,"keydown"),h(n,"focus")).pipe(xe(pe),m(()=>n.value),Y());return o.pipe(De(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(v(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(v(Sr),m(({data:a})=>a)).pipe(S(a=>o.next(a)),A(()=>o.complete()),m(()=>({ref:e})))}function Si(e,{index$:t,keyboard$:r}){let o=Te();try{let n=gi(o.search,t),i=Ce("search-query",e),s=Ce("search-result",e);h(e,"click").pipe(v(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>it("search",!1)),r.pipe(v(({mode:c})=>c==="search")).subscribe(c=>{let p=Ve();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of M(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}c.claim()}break;case"Escape":case"Tab":it("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...M(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Ve()&&i.focus()}}),r.pipe(v(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=yi(i,{worker$:n});return O(a,Ei(s,{worker$:n,query$:a})).pipe(Ne(...me("search-share",e).map(c=>wi(c,{query$:a})),...me("search-suggest",e).map(c=>Ti(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,et}}function Oi(e,{index$:t,location$:r}){return V([t,r.pipe(K(we()),v(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>vi(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=y("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function vs(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return V([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Y((i,s)=>i.height===s.height&&i.locked===s.locked))}function co(e,o){var n=o,{header$:t}=n,r=ho(n,["header$"]);let i=F(".md-sidebar__scrollwrap",e),{y:s}=Qe(i);return k(()=>{let a=new T,c=a.pipe(re(),ae(!0)),p=a.pipe($e(0,ge));return p.pipe(te(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(Re()).subscribe(()=>{for(let l of M(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2})}}}),fe(M("label[tabindex]",e)).pipe(J(l=>h(l,"click").pipe(xe(pe),m(()=>l),W(c)))).subscribe(l=>{let f=F(`[id="${l.htmlFor}"]`);F(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Q("content.tooltips")&&fe(M("abbr[title]",e)).pipe(J(l=>Je(l,{viewport$})),W(c)).subscribe(),vs(e,r).pipe(S(l=>a.next(l)),A(()=>a.complete()),m(l=>j({ref:e},l)))})}function Li(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return bt(Ge(`${r}/releases/latest`).pipe(ye(()=>x),m(o=>({version:o.tag_name})),rt({})),Ge(r).pipe(ye(()=>x),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),rt({}))).pipe(m(([o,n])=>j(j({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ge(r).pipe(m(o=>({repositories:o.public_repos})),rt({}))}}function Mi(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ge(r).pipe(ye(()=>x),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),rt({}))}function _i(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return Li(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return Mi(r,o)}return x}var gs;function xs(e){return gs||(gs=k(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(me("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return x}return _i(e.href).pipe(S(o=>__md_set("__source",o,sessionStorage)))}).pipe(ye(()=>x),v(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function Ai(e){let t=F(":scope > :last-child",e);return k(()=>{let r=new T;return r.subscribe(({facts:o})=>{t.appendChild(Rn(o)),t.classList.add("md-source__repository--active")}),xs(e).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function ys(e,{viewport$:t,header$:r}){return Le(document.body).pipe(b(()=>Er(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),oe("hidden"))}function Ci(e,t){return k(()=>{let r=new T;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(Q("navigation.tabs.sticky")?$({hidden:!1}):ys(e,t)).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Es(e,{viewport$:t,header$:r}){let o=new Map,n=M(".md-nav__link",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=ue(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(oe("height"),m(({height:a})=>{let c=Ce("main"),p=F(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Le(document.body).pipe(oe("height"),b(a=>k(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),De(i),b(([c,p])=>t.pipe(Ut(([l,f],{offset:{y:u},size:d})=>{let g=u+d.height>=Math.floor(a.height);for(;f.length;){let[,L]=f[0];if(L-p=u&&!g)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),K({prev:[],next:[]}),tt(2,1),m(([a,c])=>a.prev.length{let i=new T,s=i.pipe(re(),ae(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),Q("toc.follow")){let a=O(t.pipe(Ae(1),m(()=>{})),t.pipe(Ae(250),m(()=>"smooth")));i.pipe(v(({prev:c})=>c.length>0),De(o.pipe(xe(pe))),te(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=vr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2,behavior:p})}}})}return Q("navigation.tracking")&&t.pipe(W(s),oe("offset"),Ae(250),Pe(1),W(n.pipe(Pe(1))),vt({delay:250}),te(i)).subscribe(([,{prev:a}])=>{let c=we(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Es(e,{viewport$:t,header$:r}).pipe(S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))})}function ws(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),tt(2,1),m(([s,a])=>s>a&&a>0),Y()),i=r.pipe(m(({active:s})=>s));return V([i,n]).pipe(m(([s,a])=>!(s&&a)),Y(),W(o.pipe(Pe(1))),ae(!0),vt({delay:250}),m(s=>({hidden:s})))}function ki(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new T,s=i.pipe(re(),ae(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(W(s),oe("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),h(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),ws(e,{viewport$:t,main$:o,target$:n}).pipe(S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))}function $i({document$:e,viewport$:t}){e.pipe(b(()=>M(".md-ellipsis")),J(r=>lt(r).pipe(W(e.pipe(Pe(1))),v(o=>o),m(()=>r),Ee(1))),v(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,Je(n,{viewport$:t}).pipe(W(e.pipe(Pe(1))),A(()=>n.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>M(".md-status")),J(r=>Je(r,{viewport$:t}))).subscribe()}function Ri({document$:e,tablet$:t}){e.pipe(b(()=>M(".md-toggle--indeterminate")),S(r=>{r.indeterminate=!0,r.checked=!1}),J(r=>h(r,"change").pipe(Jr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),te(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function Ts(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Pi({document$:e}){e.pipe(b(()=>M("[data-md-scrollfix]")),S(t=>t.removeAttribute("data-md-scrollfix")),v(Ts),J(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ii({viewport$:e,tablet$:t}){V([Be("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>$(r).pipe(ot(r?400:100))),te(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function Ss(){return location.protocol==="file:"?At(`${new URL("search/search_index.js",Or.base)}`).pipe(m(()=>__index),X(1)):Ge(new URL("search/search_index.json",Or.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var st=on(),Kt=dn(),$t=vn(Kt),po=un(),He=Sn(),Lr=Wt("(min-width: 960px)"),ji=Wt("(min-width: 1220px)"),Ui=gn(),Or=Te(),Wi=document.forms.namedItem("search")?Ss():et,lo=new T;pi({alert$:lo});ci({document$:st});var mo=new T,Di=kt(Or.base);Q("navigation.instant")&&ui({sitemap$:Di,location$:Kt,viewport$:He,progress$:mo}).subscribe(st);var Fi;((Fi=Or.version)==null?void 0:Fi.provider)==="mike"&&xi({document$:st});O(Kt,$t).pipe(ot(125)).subscribe(()=>{it("drawer",!1),it("search",!1)});po.pipe(v(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=ue("link[rel=prev]");typeof t!="undefined"&&at(t);break;case"n":case".":let r=ue("link[rel=next]");typeof r!="undefined"&&at(r);break;case"Enter":let o=Ve();o instanceof HTMLLabelElement&&o.click()}});$i({viewport$:He,document$:st});Ri({document$:st,tablet$:Lr});Pi({document$:st});Ii({viewport$:He,tablet$:Lr});var mt=ti(Ce("header"),{viewport$:He}),qt=st.pipe(m(()=>Ce("main")),b(e=>ni(e,{viewport$:He,header$:mt})),X(1)),Os=O(...me("consent").map(e=>Mn(e,{target$:$t})),...me("dialog").map(e=>Zn(e,{alert$:lo})),...me("header").map(e=>ri(e,{viewport$:He,header$:mt,main$:qt})),...me("palette").map(e=>ii(e)),...me("progress").map(e=>ai(e,{progress$:mo})),...me("search").map(e=>Si(e,{index$:Wi,keyboard$:po})),...me("source").map(e=>Ai(e))),Ls=k(()=>O(...me("announce").map(e=>Ln(e)),...me("content").map(e=>Xn(e,{sitemap$:Di,viewport$:He,target$:$t,print$:Ui})),...me("content").map(e=>Q("search.highlight")?Oi(e,{index$:Wi,location$:Kt}):x),...me("header-title").map(e=>oi(e,{viewport$:He,header$:mt})),...me("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?eo(ji,()=>co(e,{viewport$:He,header$:mt,main$:qt})):eo(Lr,()=>co(e,{viewport$:He,header$:mt,main$:qt}))),...me("tabs").map(e=>Ci(e,{viewport$:He,header$:mt})),...me("toc").map(e=>Hi(e,{viewport$:He,header$:mt,main$:qt,target$:$t})),...me("top").map(e=>ki(e,{viewport$:He,header$:mt,main$:qt,target$:$t})))),Ni=st.pipe(b(()=>Ls),Ne(Os),X(1));Ni.subscribe();window.document$=st;window.location$=Kt;window.target$=$t;window.keyboard$=po;window.viewport$=He;window.tablet$=Lr;window.screen$=ji;window.print$=Ui;window.alert$=lo;window.progress$=mo;window.component$=Ni;})(); diff --git a/assets/javascripts/lunr/min/lunr.ar.min.js b/assets/javascripts/lunr/min/lunr.ar.min.js new file mode 100644 index 000000000..9b06c26c1 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ar.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ar=function(){this.pipeline.reset(),this.pipeline.add(e.ar.trimmer,e.ar.stopWordFilter,e.ar.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ar.stemmer))},e.ar.wordCharacters="ء-ٛٱـ",e.ar.trimmer=e.trimmerSupport.generateTrimmer(e.ar.wordCharacters),e.Pipeline.registerFunction(e.ar.trimmer,"trimmer-ar"),e.ar.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ف ك ب و س ل ن ا ي ت",pre2:"ال لل",pre3:"بال وال فال تال كال ولل",pre4:"فبال كبال وبال وكال"},e.suf={suf1:"ه ك ت ن ا ي",suf2:"نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه",suf3:"تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها",suf4:"كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا"},e.patterns=JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}'),e.execArray=["cleanWord","removeDiacritics","cleanAlef","removeStopWords","normalizeHamzaAndAlef","removeStartWaw","removePre432","removeEndTaa","wordCheck"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHamzaAndAlef=function(){return e.word=e.word.replace("ؤ","ء"),e.word=e.word.replace("ئ","ء"),e.word=e.word.replace(/([\u0627])\1+/gi,"ا"),!1},e.removeEndTaa=function(){return!(e.word.length>2)||(e.word=e.word.replace(/[\u0627]$/,""),e.word=e.word.replace("ة",""),!1)},e.removeStartWaw=function(){return e.word.length>3&&"و"==e.word[0]&&"و"==e.word[1]&&(e.word=e.word.slice(1)),!1},e.removePre432=function(){var r=e.word;if(e.word.length>=7){var t=new RegExp("^("+e.pre.pre4.split(" ").join("|")+")");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=6){var c=new RegExp("^("+e.pre.pre3.split(" ").join("|")+")");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=5){var l=new RegExp("^("+e.pre.pre2.split(" ").join("|")+")");e.word=e.word.replace(l,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.patternCheck=function(r){for(var t=0;t3){var t=new RegExp("^("+e.pre.pre1.split(" ").join("|")+")");e.word=e.word.replace(t,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.removeSuf1=function(){var r=e.word;if(0==e.sufRemoved&&e.word.length>3){var t=new RegExp("("+e.suf.suf1.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.removeSuf432=function(){var r=e.word;if(e.word.length>=6){var t=new RegExp("("+e.suf.suf4.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=5){var c=new RegExp("("+e.suf.suf3.split(" ").join("|")+")$");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=4){var l=new RegExp("("+e.suf.suf2.split(" ").join("|")+")$");e.word=e.word.replace(l,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.wordCheck=function(){for(var r=(e.word,[e.removeSuf432,e.removeSuf1,e.removePre1]),t=0,c=!1;e.word.length>=7&&!e.result&&t=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.de.min.js b/assets/javascripts/lunr/min/lunr.de.min.js new file mode 100644 index 000000000..f3b5c108c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.de.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `German` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.du.min.js b/assets/javascripts/lunr/min/lunr.du.min.js new file mode 100644 index 000000000..49a0f3f0a --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.du.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Dutch` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.el.min.js b/assets/javascripts/lunr/min/lunr.el.min.js new file mode 100644 index 000000000..ace017bd6 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.el.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.el=function(){this.pipeline.reset(),void 0===this.searchPipeline&&this.pipeline.add(e.el.trimmer,e.el.normilizer),this.pipeline.add(e.el.stopWordFilter,e.el.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.el.stemmer))},e.el.wordCharacters="A-Za-zΑαΒβΓγΔδΕεΖζΗηΘθΙιΚκΛλΜμΝνΞξΟοΠπΡρΣσςΤτΥυΦφΧχΨψΩωΆάΈέΉήΊίΌόΎύΏώΪΐΫΰΐΰ",e.el.trimmer=e.trimmerSupport.generateTrimmer(e.el.wordCharacters),e.Pipeline.registerFunction(e.el.trimmer,"trimmer-el"),e.el.stemmer=function(){function e(e){return s.test(e)}function t(e){return/[ΑΕΗΙΟΥΩ]$/.test(e)}function r(e){return/[ΑΕΗΙΟΩ]$/.test(e)}function n(n){var s=n;if(n.length<3)return s;if(!e(n))return s;if(i.indexOf(n)>=0)return s;var u=new RegExp("(.*)("+Object.keys(l).join("|")+")$"),o=u.exec(s);return null!==o&&(s=o[1]+l[o[2]]),null!==(o=/^(.+?)(ΑΔΕΣ|ΑΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΚ|ΜΑΜ|ΜΑΝ|ΜΠΑΜΠ|ΠΑΤΕΡ|ΓΙΑΓΙ|ΝΤΑΝΤ|ΚΥΡ|ΘΕΙ|ΠΕΘΕΡ|ΜΟΥΣΑΜ|ΚΑΠΛΑΜ|ΠΑΡ|ΨΑΡ|ΤΖΟΥΡ|ΤΑΜΠΟΥΡ|ΓΑΛΑΤ|ΦΑΦΛΑΤ)$/.test(o[1])||(s+="ΑΔ")),null!==(o=/^(.+?)(ΕΔΕΣ|ΕΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΠ|ΙΠ|ΕΜΠ|ΥΠ|ΓΗΠ|ΔΑΠ|ΚΡΑΣΠ|ΜΙΛ)$/.test(o[1])&&(s+="ΕΔ")),null!==(o=/^(.+?)(ΟΥΔΕΣ|ΟΥΔΩΝ)$/.exec(s))&&(s=o[1],/(ΑΡΚ|ΚΑΛΙΑΚ|ΠΕΤΑΛ|ΛΙΧ|ΠΛΕΞ|ΣΚ|Σ|ΦΛ|ΦΡ|ΒΕΛ|ΛΟΥΛ|ΧΝ|ΣΠ|ΤΡΑΓ|ΦΕ)$/.test(o[1])&&(s+="ΟΥΔ")),null!==(o=/^(.+?)(ΕΩΣ|ΕΩΝ|ΕΑΣ|ΕΑ)$/.exec(s))&&(s=o[1],/^(Θ|Δ|ΕΛ|ΓΑΛ|Ν|Π|ΙΔ|ΠΑΡ|ΣΤΕΡ|ΟΡΦ|ΑΝΔΡ|ΑΝΤΡ)$/.test(o[1])&&(s+="Ε")),null!==(o=/^(.+?)(ΕΙΟ|ΕΙΟΣ|ΕΙΟΙ|ΕΙΑ|ΕΙΑΣ|ΕΙΕΣ|ΕΙΟΥ|ΕΙΟΥΣ|ΕΙΩΝ)$/.exec(s))&&o[1].length>4&&(s=o[1]),null!==(o=/^(.+?)(ΙΟΥΣ|ΙΑΣ|ΙΕΣ|ΙΟΣ|ΙΟΥ|ΙΟΙ|ΙΩΝ|ΙΟΝ|ΙΑ|ΙΟ)$/.exec(s))&&(s=o[1],(t(s)||s.length<2||/^(ΑΓ|ΑΓΓΕΛ|ΑΓΡ|ΑΕΡ|ΑΘΛ|ΑΚΟΥΣ|ΑΞ|ΑΣ|Β|ΒΙΒΛ|ΒΥΤ|Γ|ΓΙΑΓ|ΓΩΝ|Δ|ΔΑΝ|ΔΗΛ|ΔΗΜ|ΔΟΚΙΜ|ΕΛ|ΖΑΧΑΡ|ΗΛ|ΗΠ|ΙΔ|ΙΣΚ|ΙΣΤ|ΙΟΝ|ΙΩΝ|ΚΙΜΩΛ|ΚΟΛΟΝ|ΚΟΡ|ΚΤΗΡ|ΚΥΡ|ΛΑΓ|ΛΟΓ|ΜΑΓ|ΜΠΑΝ|ΜΠΡ|ΝΑΥΤ|ΝΟΤ|ΟΠΑΛ|ΟΞ|ΟΡ|ΟΣ|ΠΑΝΑΓ|ΠΑΤΡ|ΠΗΛ|ΠΗΝ|ΠΛΑΙΣ|ΠΟΝΤ|ΡΑΔ|ΡΟΔ|ΣΚ|ΣΚΟΡΠ|ΣΟΥΝ|ΣΠΑΝ|ΣΤΑΔ|ΣΥΡ|ΤΗΛ|ΤΙΜ|ΤΟΚ|ΤΟΠ|ΤΡΟΧ|ΦΙΛ|ΦΩΤ|Χ|ΧΙΛ|ΧΡΩΜ|ΧΩΡ)$/.test(o[1]))&&(s+="Ι"),/^(ΠΑΛ)$/.test(o[1])&&(s+="ΑΙ")),null!==(o=/^(.+?)(ΙΚΟΣ|ΙΚΟΝ|ΙΚΕΙΣ|ΙΚΟΙ|ΙΚΕΣ|ΙΚΟΥΣ|ΙΚΗ|ΙΚΗΣ|ΙΚΟ|ΙΚΑ|ΙΚΟΥ|ΙΚΩΝ|ΙΚΩΣ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΑΔ|ΑΛ|ΑΜΑΝ|ΑΜΕΡ|ΑΜΜΟΧΑΛ|ΑΝΗΘ|ΑΝΤΙΔ|ΑΠΛ|ΑΤΤ|ΑΦΡ|ΒΑΣ|ΒΡΩΜ|ΓΕΝ|ΓΕΡ|Δ|ΔΙΚΑΝ|ΔΥΤ|ΕΙΔ|ΕΝΔ|ΕΞΩΔ|ΗΘ|ΘΕΤ|ΚΑΛΛΙΝ|ΚΑΛΠ|ΚΑΤΑΔ|ΚΟΥΖΙΝ|ΚΡ|ΚΩΔ|ΛΟΓ|Μ|ΜΕΡ|ΜΟΝΑΔ|ΜΟΥΛ|ΜΟΥΣ|ΜΠΑΓΙΑΤ|ΜΠΑΝ|ΜΠΟΛ|ΜΠΟΣ|ΜΥΣΤ|Ν|ΝΙΤ|ΞΙΚ|ΟΠΤ|ΠΑΝ|ΠΕΤΣ|ΠΙΚΑΝΤ|ΠΙΤΣ|ΠΛΑΣΤ|ΠΛΙΑΤΣ|ΠΟΝΤ|ΠΟΣΤΕΛΝ|ΠΡΩΤΟΔ|ΣΕΡΤ|ΣΗΜΑΝΤ|ΣΤΑΤ|ΣΥΝΑΔ|ΣΥΝΟΜΗΛ|ΤΕΛ|ΤΕΧΝ|ΤΡΟΠ|ΤΣΑΜ|ΥΠΟΔ|Φ|ΦΙΛΟΝ|ΦΥΛΟΔ|ΦΥΣ|ΧΑΣ)$/.test(o[1])||/(ΦΟΙΝ)$/.test(o[1]))&&(s+="ΙΚ")),"ΑΓΑΜΕ"===s&&(s="ΑΓΑΜ"),null!==(o=/^(.+?)(ΑΓΑΜΕ|ΗΣΑΜΕ|ΟΥΣΑΜΕ|ΗΚΑΜΕ|ΗΘΗΚΑΜΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΑΜΕ)$/.exec(s))&&(s=o[1],/^(ΑΝΑΠ|ΑΠΟΘ|ΑΠΟΚ|ΑΠΟΣΤ|ΒΟΥΒ|ΞΕΘ|ΟΥΛ|ΠΕΘ|ΠΙΚΡ|ΠΟΤ|ΣΙΧ|Χ)$/.test(o[1])&&(s+="ΑΜ")),null!==(o=/^(.+?)(ΑΓΑΝΕ|ΗΣΑΝΕ|ΟΥΣΑΝΕ|ΙΟΝΤΑΝΕ|ΙΟΤΑΝΕ|ΙΟΥΝΤΑΝΕ|ΟΝΤΑΝΕ|ΟΤΑΝΕ|ΟΥΝΤΑΝΕ|ΗΚΑΝΕ|ΗΘΗΚΑΝΕ)$/.exec(s))&&(s=o[1],/^(ΤΡ|ΤΣ)$/.test(o[1])&&(s+="ΑΓΑΝ")),null!==(o=/^(.+?)(ΑΝΕ)$/.exec(s))&&(s=o[1],(r(s)||/^(ΒΕΤΕΡ|ΒΟΥΛΚ|ΒΡΑΧΜ|Γ|ΔΡΑΔΟΥΜ|Θ|ΚΑΛΠΟΥΖ|ΚΑΣΤΕΛ|ΚΟΡΜΟΡ|ΛΑΟΠΛ|ΜΩΑΜΕΘ|Μ|ΜΟΥΣΟΥΛΜΑΝ|ΟΥΛ|Π|ΠΕΛΕΚ|ΠΛ|ΠΟΛΙΣ|ΠΟΡΤΟΛ|ΣΑΡΑΚΑΤΣ|ΣΟΥΛΤ|ΤΣΑΡΛΑΤ|ΟΡΦ|ΤΣΙΓΓ|ΤΣΟΠ|ΦΩΤΟΣΤΕΦ|Χ|ΨΥΧΟΠΛ|ΑΓ|ΟΡΦ|ΓΑΛ|ΓΕΡ|ΔΕΚ|ΔΙΠΛ|ΑΜΕΡΙΚΑΝ|ΟΥΡ|ΠΙΘ|ΠΟΥΡΙΤ|Σ|ΖΩΝΤ|ΙΚ|ΚΑΣΤ|ΚΟΠ|ΛΙΧ|ΛΟΥΘΗΡ|ΜΑΙΝΤ|ΜΕΛ|ΣΙΓ|ΣΠ|ΣΤΕΓ|ΤΡΑΓ|ΤΣΑΓ|Φ|ΕΡ|ΑΔΑΠ|ΑΘΙΓΓ|ΑΜΗΧ|ΑΝΙΚ|ΑΝΟΡΓ|ΑΠΗΓ|ΑΠΙΘ|ΑΤΣΙΓΓ|ΒΑΣ|ΒΑΣΚ|ΒΑΘΥΓΑΛ|ΒΙΟΜΗΧ|ΒΡΑΧΥΚ|ΔΙΑΤ|ΔΙΑΦ|ΕΝΟΡΓ|ΘΥΣ|ΚΑΠΝΟΒΙΟΜΗΧ|ΚΑΤΑΓΑΛ|ΚΛΙΒ|ΚΟΙΛΑΡΦ|ΛΙΒ|ΜΕΓΛΟΒΙΟΜΗΧ|ΜΙΚΡΟΒΙΟΜΗΧ|ΝΤΑΒ|ΞΗΡΟΚΛΙΒ|ΟΛΙΓΟΔΑΜ|ΟΛΟΓΑΛ|ΠΕΝΤΑΡΦ|ΠΕΡΗΦ|ΠΕΡΙΤΡ|ΠΛΑΤ|ΠΟΛΥΔΑΠ|ΠΟΛΥΜΗΧ|ΣΤΕΦ|ΤΑΒ|ΤΕΤ|ΥΠΕΡΗΦ|ΥΠΟΚΟΠ|ΧΑΜΗΛΟΔΑΠ|ΨΗΛΟΤΑΒ)$/.test(o[1]))&&(s+="ΑΝ")),null!==(o=/^(.+?)(ΗΣΕΤΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΕΤΕ)$/.exec(s))&&(s=o[1],(r(s)||/(ΟΔ|ΑΙΡ|ΦΟΡ|ΤΑΘ|ΔΙΑΘ|ΣΧ|ΕΝΔ|ΕΥΡ|ΤΙΘ|ΥΠΕΡΘ|ΡΑΘ|ΕΝΘ|ΡΟΘ|ΣΘ|ΠΥΡ|ΑΙΝ|ΣΥΝΔ|ΣΥΝ|ΣΥΝΘ|ΧΩΡ|ΠΟΝ|ΒΡ|ΚΑΘ|ΕΥΘ|ΕΚΘ|ΝΕΤ|ΡΟΝ|ΑΡΚ|ΒΑΡ|ΒΟΛ|ΩΦΕΛ)$/.test(o[1])||/^(ΑΒΑΡ|ΒΕΝ|ΕΝΑΡ|ΑΒΡ|ΑΔ|ΑΘ|ΑΝ|ΑΠΛ|ΒΑΡΟΝ|ΝΤΡ|ΣΚ|ΚΟΠ|ΜΠΟΡ|ΝΙΦ|ΠΑΓ|ΠΑΡΑΚΑΛ|ΣΕΡΠ|ΣΚΕΛ|ΣΥΡΦ|ΤΟΚ|Υ|Δ|ΕΜ|ΘΑΡΡ|Θ)$/.test(o[1]))&&(s+="ΕΤ")),null!==(o=/^(.+?)(ΟΝΤΑΣ|ΩΝΤΑΣ)$/.exec(s))&&(s=o[1],/^ΑΡΧ$/.test(o[1])&&(s+="ΟΝΤ"),/ΚΡΕ$/.test(o[1])&&(s+="ΩΝΤ")),null!==(o=/^(.+?)(ΟΜΑΣΤΕ|ΙΟΜΑΣΤΕ)$/.exec(s))&&(s=o[1],/^ΟΝ$/.test(o[1])&&(s+="ΟΜΑΣΤ")),null!==(o=/^(.+?)(ΙΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(Π|ΑΠ|ΣΥΜΠ|ΑΣΥΜΠ|ΑΚΑΤΑΠ|ΑΜΕΤΑΜΦ)$/.test(o[1])&&(s+="ΙΕΣΤ")),null!==(o=/^(.+?)(ΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΛ|ΑΡ|ΕΚΤΕΛ|Ζ|Μ|Ξ|ΠΑΡΑΚΑΛ|ΠΡΟ|ΝΙΣ)$/.test(o[1])&&(s+="ΕΣΤ")),null!==(o=/^(.+?)(ΗΘΗΚΑ|ΗΘΗΚΕΣ|ΗΘΗΚΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΗΚΑ|ΗΚΕΣ|ΗΚΕ)$/.exec(s))&&(s=o[1],(/(ΣΚΩΛ|ΣΚΟΥΛ|ΝΑΡΘ|ΣΦ|ΟΘ|ΠΙΘ)$/.test(o[1])||/^(ΔΙΑΘ|Θ|ΠΑΡΑΚΑΤΑΘ|ΠΡΟΣΘ|ΣΥΝΘ)$/.test(o[1]))&&(s+="ΗΚ")),null!==(o=/^(.+?)(ΟΥΣΑ|ΟΥΣΕΣ|ΟΥΣΕ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΦΑΡΜΑΚ|ΧΑΔ|ΑΓΚ|ΑΝΑΡΡ|ΒΡΟΜ|ΕΚΛΙΠ|ΛΑΜΠΙΔ|ΛΕΧ|Μ|ΠΑΤ|Ρ|Λ|ΜΕΔ|ΜΕΣΑΖ|ΥΠΟΤΕΙΝ|ΑΜ|ΑΙΘ|ΑΝΗΚ|ΔΕΣΠΟΖ|ΕΝΔΙΑΦΕΡ)$/.test(o[1])||/(ΠΟΔΑΡ|ΒΛΕΠ|ΠΑΝΤΑΧ|ΦΡΥΔ|ΜΑΝΤΙΛ|ΜΑΛΛ|ΚΥΜΑΤ|ΛΑΧ|ΛΗΓ|ΦΑΓ|ΟΜ|ΠΡΩΤ)$/.test(o[1]))&&(s+="ΟΥΣ")),null!==(o=/^(.+?)(ΑΓΑ|ΑΓΕΣ|ΑΓΕ)$/.exec(s))&&(s=o[1],(/^(ΑΒΑΣΤ|ΠΟΛΥΦ|ΑΔΗΦ|ΠΑΜΦ|Ρ|ΑΣΠ|ΑΦ|ΑΜΑΛ|ΑΜΑΛΛΙ|ΑΝΥΣΤ|ΑΠΕΡ|ΑΣΠΑΡ|ΑΧΑΡ|ΔΕΡΒΕΝ|ΔΡΟΣΟΠ|ΞΕΦ|ΝΕΟΠ|ΝΟΜΟΤ|ΟΛΟΠ|ΟΜΟΤ|ΠΡΟΣΤ|ΠΡΟΣΩΠΟΠ|ΣΥΜΠ|ΣΥΝΤ|Τ|ΥΠΟΤ|ΧΑΡ|ΑΕΙΠ|ΑΙΜΟΣΤ|ΑΝΥΠ|ΑΠΟΤ|ΑΡΤΙΠ|ΔΙΑΤ|ΕΝ|ΕΠΙΤ|ΚΡΟΚΑΛΟΠ|ΣΙΔΗΡΟΠ|Λ|ΝΑΥ|ΟΥΛΑΜ|ΟΥΡ|Π|ΤΡ|Μ)$/.test(o[1])||/(ΟΦ|ΠΕΛ|ΧΟΡΤ|ΛΛ|ΣΦ|ΡΠ|ΦΡ|ΠΡ|ΛΟΧ|ΣΜΗΝ)$/.test(o[1])&&!/^(ΨΟΦ|ΝΑΥΛΟΧ)$/.test(o[1])||/(ΚΟΛΛ)$/.test(o[1]))&&(s+="ΑΓ")),null!==(o=/^(.+?)(ΗΣΕ|ΗΣΟΥ|ΗΣΑ)$/.exec(s))&&(s=o[1],/^(Ν|ΧΕΡΣΟΝ|ΔΩΔΕΚΑΝ|ΕΡΗΜΟΝ|ΜΕΓΑΛΟΝ|ΕΠΤΑΝ|Ι)$/.test(o[1])&&(s+="ΗΣ")),null!==(o=/^(.+?)(ΗΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΣΒ|ΣΒ|ΑΧΡ|ΧΡ|ΑΠΛ|ΑΕΙΜΝ|ΔΥΣΧΡ|ΕΥΧΡ|ΚΟΙΝΟΧΡ|ΠΑΛΙΜΨ)$/.test(o[1])&&(s+="ΗΣΤ")),null!==(o=/^(.+?)(ΟΥΝΕ|ΗΣΟΥΝΕ|ΗΘΟΥΝΕ)$/.exec(s))&&(s=o[1],/^(Ν|Ρ|ΣΠΙ|ΣΤΡΑΒΟΜΟΥΤΣ|ΚΑΚΟΜΟΥΤΣ|ΕΞΩΝ)$/.test(o[1])&&(s+="ΟΥΝ")),null!==(o=/^(.+?)(ΟΥΜΕ|ΗΣΟΥΜΕ|ΗΘΟΥΜΕ)$/.exec(s))&&(s=o[1],/^(ΠΑΡΑΣΟΥΣ|Φ|Χ|ΩΡΙΟΠΛ|ΑΖ|ΑΛΛΟΣΟΥΣ|ΑΣΟΥΣ)$/.test(o[1])&&(s+="ΟΥΜ")),null!=(o=/^(.+?)(ΜΑΤΟΙ|ΜΑΤΟΥΣ|ΜΑΤΟ|ΜΑΤΑ|ΜΑΤΩΣ|ΜΑΤΩΝ|ΜΑΤΟΣ|ΜΑΤΕΣ|ΜΑΤΗ|ΜΑΤΗΣ|ΜΑΤΟΥ)$/.exec(s))&&(s=o[1]+"Μ",/^(ΓΡΑΜ)$/.test(o[1])?s+="Α":/^(ΓΕ|ΣΤΑ)$/.test(o[1])&&(s+="ΑΤ")),null!==(o=/^(.+?)(ΟΥΑ)$/.exec(s))&&(s=o[1]+"ΟΥ"),n.length===s.length&&null!==(o=/^(.+?)(Α|ΑΓΑΤΕ|ΑΓΑΝ|ΑΕΙ|ΑΜΑΙ|ΑΝ|ΑΣ|ΑΣΑΙ|ΑΤΑΙ|ΑΩ|Ε|ΕΙ|ΕΙΣ|ΕΙΤΕ|ΕΣΑΙ|ΕΣ|ΕΤΑΙ|Ι|ΙΕΜΑΙ|ΙΕΜΑΣΤΕ|ΙΕΤΑΙ|ΙΕΣΑΙ|ΙΕΣΑΣΤΕ|ΙΟΜΑΣΤΑΝ|ΙΟΜΟΥΝ|ΙΟΜΟΥΝΑ|ΙΟΝΤΑΝ|ΙΟΝΤΟΥΣΑΝ|ΙΟΣΑΣΤΑΝ|ΙΟΣΑΣΤΕ|ΙΟΣΟΥΝ|ΙΟΣΟΥΝΑ|ΙΟΤΑΝ|ΙΟΥΜΑ|ΙΟΥΜΑΣΤΕ|ΙΟΥΝΤΑΙ|ΙΟΥΝΤΑΝ|Η|ΗΔΕΣ|ΗΔΩΝ|ΗΘΕΙ|ΗΘΕΙΣ|ΗΘΕΙΤΕ|ΗΘΗΚΑΤΕ|ΗΘΗΚΑΝ|ΗΘΟΥΝ|ΗΘΩ|ΗΚΑΤΕ|ΗΚΑΝ|ΗΣ|ΗΣΑΝ|ΗΣΑΤΕ|ΗΣΕΙ|ΗΣΕΣ|ΗΣΟΥΝ|ΗΣΩ|Ο|ΟΙ|ΟΜΑΙ|ΟΜΑΣΤΑΝ|ΟΜΟΥΝ|ΟΜΟΥΝΑ|ΟΝΤΑΙ|ΟΝΤΑΝ|ΟΝΤΟΥΣΑΝ|ΟΣ|ΟΣΑΣΤΑΝ|ΟΣΑΣΤΕ|ΟΣΟΥΝ|ΟΣΟΥΝΑ|ΟΤΑΝ|ΟΥ|ΟΥΜΑΙ|ΟΥΜΑΣΤΕ|ΟΥΝ|ΟΥΝΤΑΙ|ΟΥΝΤΑΝ|ΟΥΣ|ΟΥΣΑΝ|ΟΥΣΑΤΕ|Υ||ΥΑ|ΥΣ|Ω|ΩΝ|ΟΙΣ)$/.exec(s))&&(s=o[1]),null!=(o=/^(.+?)(ΕΣΤΕΡ|ΕΣΤΑΤ|ΟΤΕΡ|ΟΤΑΤ|ΥΤΕΡ|ΥΤΑΤ|ΩΤΕΡ|ΩΤΑΤ)$/.exec(s))&&(/^(ΕΞ|ΕΣ|ΑΝ|ΚΑΤ|Κ|ΠΡ)$/.test(o[1])||(s=o[1]),/^(ΚΑ|Μ|ΕΛΕ|ΛΕ|ΔΕ)$/.test(o[1])&&(s+="ΥΤ")),s}var l={"ΦΑΓΙΑ":"ΦΑ","ΦΑΓΙΟΥ":"ΦΑ","ΦΑΓΙΩΝ":"ΦΑ","ΣΚΑΓΙΑ":"ΣΚΑ","ΣΚΑΓΙΟΥ":"ΣΚΑ","ΣΚΑΓΙΩΝ":"ΣΚΑ","ΣΟΓΙΟΥ":"ΣΟ","ΣΟΓΙΑ":"ΣΟ","ΣΟΓΙΩΝ":"ΣΟ","ΤΑΤΟΓΙΑ":"ΤΑΤΟ","ΤΑΤΟΓΙΟΥ":"ΤΑΤΟ","ΤΑΤΟΓΙΩΝ":"ΤΑΤΟ","ΚΡΕΑΣ":"ΚΡΕ","ΚΡΕΑΤΟΣ":"ΚΡΕ","ΚΡΕΑΤΑ":"ΚΡΕ","ΚΡΕΑΤΩΝ":"ΚΡΕ","ΠΕΡΑΣ":"ΠΕΡ","ΠΕΡΑΤΟΣ":"ΠΕΡ","ΠΕΡΑΤΑ":"ΠΕΡ","ΠΕΡΑΤΩΝ":"ΠΕΡ","ΤΕΡΑΣ":"ΤΕΡ","ΤΕΡΑΤΟΣ":"ΤΕΡ","ΤΕΡΑΤΑ":"ΤΕΡ","ΤΕΡΑΤΩΝ":"ΤΕΡ","ΦΩΣ":"ΦΩ","ΦΩΤΟΣ":"ΦΩ","ΦΩΤΑ":"ΦΩ","ΦΩΤΩΝ":"ΦΩ","ΚΑΘΕΣΤΩΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΟΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΑ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΩΝ":"ΚΑΘΕΣΤ","ΓΕΓΟΝΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΑ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΩΝ":"ΓΕΓΟΝ","ΕΥΑ":"ΕΥ"},i=["ΑΚΡΙΒΩΣ","ΑΛΑ","ΑΛΛΑ","ΑΛΛΙΩΣ","ΑΛΛΟΤΕ","ΑΜΑ","ΑΝΩ","ΑΝΑ","ΑΝΑΜΕΣΑ","ΑΝΑΜΕΤΑΞΥ","ΑΝΕΥ","ΑΝΤΙ","ΑΝΤΙΠΕΡΑ","ΑΝΤΙΟ","ΑΞΑΦΝΑ","ΑΠΟ","ΑΠΟΨΕ","ΑΡΑ","ΑΡΑΓΕ","ΑΥΡΙΟ","ΑΦΟΙ","ΑΦΟΥ","ΑΦΟΤΟΥ","ΒΡΕ","ΓΕΙΑ","ΓΙΑ","ΓΙΑΤΙ","ΓΡΑΜΜΑ","ΔΕΗ","ΔΕΝ","ΔΗΛΑΔΗ","ΔΙΧΩΣ","ΔΥΟ","ΕΑΝ","ΕΓΩ","ΕΔΩ","ΕΔΑ","ΕΙΘΕ","ΕΙΜΑΙ","ΕΙΜΑΣΤΕ","ΕΙΣΑΙ","ΕΙΣΑΣΤΕ","ΕΙΝΑΙ","ΕΙΣΤΕ","ΕΙΤΕ","ΕΚΕΙ","ΕΚΟ","ΕΛΑ","ΕΜΑΣ","ΕΜΕΙΣ","ΕΝΤΕΛΩΣ","ΕΝΤΟΣ","ΕΝΤΩΜΕΤΑΞΥ","ΕΝΩ","ΕΞΙ","ΕΞΙΣΟΥ","ΕΞΗΣ","ΕΞΩ","ΕΟΚ","ΕΠΑΝΩ","ΕΠΕΙΔΗ","ΕΠΕΙΤΑ","ΕΠΙ","ΕΠΙΣΗΣ","ΕΠΟΜΕΝΩΣ","ΕΠΤΑ","ΕΣΑΣ","ΕΣΕΙΣ","ΕΣΤΩ","ΕΣΥ","ΕΣΩ","ΕΤΣΙ","ΕΥΓΕ","ΕΦΕ","ΕΦΕΞΗΣ","ΕΧΤΕΣ","ΕΩΣ","ΗΔΗ","ΗΜΙ","ΗΠΑ","ΗΤΟΙ","ΘΕΣ","ΙΔΙΩΣ","ΙΔΗ","ΙΚΑ","ΙΣΩΣ","ΚΑΘΕ","ΚΑΘΕΤΙ","ΚΑΘΟΛΟΥ","ΚΑΘΩΣ","ΚΑΙ","ΚΑΝ","ΚΑΠΟΤΕ","ΚΑΠΟΥ","ΚΑΤΑ","ΚΑΤΙ","ΚΑΤΟΠΙΝ","ΚΑΤΩ","ΚΕΙ","ΚΙΧ","ΚΚΕ","ΚΟΛΑΝ","ΚΥΡΙΩΣ","ΚΩΣ","ΜΑΚΑΡΙ","ΜΑΛΙΣΤΑ","ΜΑΛΛΟΝ","ΜΑΙ","ΜΑΟ","ΜΑΟΥΣ","ΜΑΣ","ΜΕΘΑΥΡΙΟ","ΜΕΣ","ΜΕΣΑ","ΜΕΤΑ","ΜΕΤΑΞΥ","ΜΕΧΡΙ","ΜΗΔΕ","ΜΗΝ","ΜΗΠΩΣ","ΜΗΤΕ","ΜΙΑ","ΜΙΑΣ","ΜΙΣ","ΜΜΕ","ΜΟΛΟΝΟΤΙ","ΜΟΥ","ΜΠΑ","ΜΠΑΣ","ΜΠΟΥΦΑΝ","ΜΠΡΟΣ","ΝΑΙ","ΝΕΣ","ΝΤΑ","ΝΤΕ","ΞΑΝΑ","ΟΗΕ","ΟΚΤΩ","ΟΜΩΣ","ΟΝΕ","ΟΠΑ","ΟΠΟΥ","ΟΠΩΣ","ΟΣΟ","ΟΤΑΝ","ΟΤΕ","ΟΤΙ","ΟΥΤΕ","ΟΧΙ","ΠΑΛΙ","ΠΑΝ","ΠΑΝΟ","ΠΑΝΤΟΤΕ","ΠΑΝΤΟΥ","ΠΑΝΤΩΣ","ΠΑΝΩ","ΠΑΡΑ","ΠΕΡΑ","ΠΕΡΙ","ΠΕΡΙΠΟΥ","ΠΙΑ","ΠΙΟ","ΠΙΣΩ","ΠΛΑΙ","ΠΛΕΟΝ","ΠΛΗΝ","ΠΟΤΕ","ΠΟΥ","ΠΡΟ","ΠΡΟΣ","ΠΡΟΧΤΕΣ","ΠΡΟΧΘΕΣ","ΡΟΔΙ","ΠΩΣ","ΣΑΙ","ΣΑΣ","ΣΑΝ","ΣΕΙΣ","ΣΙΑ","ΣΚΙ","ΣΟΙ","ΣΟΥ","ΣΡΙ","ΣΥΝ","ΣΥΝΑΜΑ","ΣΧΕΔΟΝ","ΤΑΔΕ","ΤΑΞΙ","ΤΑΧΑ","ΤΕΙ","ΤΗΝ","ΤΗΣ","ΤΙΠΟΤΑ","ΤΙΠΟΤΕ","ΤΙΣ","ΤΟΝ","ΤΟΤΕ","ΤΟΥ","ΤΟΥΣ","ΤΣΑ","ΤΣΕ","ΤΣΙ","ΤΣΟΥ","ΤΩΝ","ΥΠΟ","ΥΠΟΨΗ","ΥΠΟΨΙΝ","ΥΣΤΕΡΑ","ΦΕΤΟΣ","ΦΙΣ","ΦΠΑ","ΧΑΦ","ΧΘΕΣ","ΧΤΕΣ","ΧΩΡΙΣ","ΩΣ","ΩΣΑΝ","ΩΣΟΤΟΥ","ΩΣΠΟΥ","ΩΣΤΕ","ΩΣΤΟΣΟ"],s=new RegExp("^[ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ]+$");return function(e){return"function"==typeof e.update?e.update(function(e){return n(e.toUpperCase()).toLowerCase()}):n(e.toUpperCase()).toLowerCase()}}(),e.Pipeline.registerFunction(e.el.stemmer,"stemmer-el"),e.el.stopWordFilter=e.generateStopWordFilter("αλλα αν αντι απο αυτα αυτεσ αυτη αυτο αυτοι αυτοσ αυτουσ αυτων για δε δεν εαν ειμαι ειμαστε ειναι εισαι ειστε εκεινα εκεινεσ εκεινη εκεινο εκεινοι εκεινοσ εκεινουσ εκεινων ενω επι η θα ισωσ κ και κατα κι μα με μετα μη μην να ο οι ομωσ οπωσ οσο οτι παρα ποια ποιεσ ποιο ποιοι ποιοσ ποιουσ ποιων που προσ πωσ σε στη στην στο στον τα την τησ το τον τοτε του των ωσ".split(" ")),e.Pipeline.registerFunction(e.el.stopWordFilter,"stopWordFilter-el"),e.el.normilizer=function(){var e={"Ά":"Α","ά":"α","Έ":"Ε","έ":"ε","Ή":"Η","ή":"η","Ί":"Ι","ί":"ι","Ό":"Ο","ο":"ο","Ύ":"Υ","ύ":"υ","Ώ":"Ω","ώ":"ω","Ϊ":"Ι","ϊ":"ι","Ϋ":"Υ","ϋ":"υ","ΐ":"ι","ΰ":"υ"};return function(t){if("function"==typeof t.update)return t.update(function(t){for(var r="",n=0;n=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fi.min.js b/assets/javascripts/lunr/min/lunr.fi.min.js new file mode 100644 index 000000000..29f5dfcea --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fi.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Finnish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fr.min.js b/assets/javascripts/lunr/min/lunr.fr.min.js new file mode 100644 index 000000000..68cd0094a --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `French` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.he.min.js b/assets/javascripts/lunr/min/lunr.he.min.js new file mode 100644 index 000000000..b863d3eae --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.he.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.he=function(){this.pipeline.reset(),this.pipeline.add(e.he.trimmer,e.he.stopWordFilter,e.he.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.he.stemmer))},e.he.wordCharacters="֑-״א-תa-zA-Za-zA-Z0-90-9",e.he.trimmer=e.trimmerSupport.generateTrimmer(e.he.wordCharacters),e.Pipeline.registerFunction(e.he.trimmer,"trimmer-he"),e.he.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ה ו י ת",pre2:"ב כ ל מ ש כש",pre3:"הב הכ הל המ הש בש לכ",pre4:"וב וכ ול ומ וש",pre5:"מה שה כל",pre6:"מב מכ מל ממ מש",pre7:"בה בו בי בת כה כו כי כת לה לו לי לת",pre8:"ובה ובו ובי ובת וכה וכו וכי וכת ולה ולו ולי ולת"},e.suf={suf1:"ך כ ם ן נ",suf2:"ים ות וך וכ ום ון ונ הם הן יכ יך ינ ים",suf3:"תי תך תכ תם תן תנ",suf4:"ותי ותך ותכ ותם ותן ותנ",suf5:"נו כם כן הם הן",suf6:"ונו וכם וכן והם והן",suf7:"תכם תכן תנו תהם תהן",suf8:"הוא היא הם הן אני אתה את אנו אתם אתן",suf9:"ני נו כי כו כם כן תי תך תכ תם תן",suf10:"י ך כ ם ן נ ת"},e.patterns=JSON.parse('{"hebrewPatterns": [{"pt1": [{"c": "ה", "l": 0}]}, {"pt2": [{"c": "ו", "l": 0}]}, {"pt3": [{"c": "י", "l": 0}]}, {"pt4": [{"c": "ת", "l": 0}]}, {"pt5": [{"c": "מ", "l": 0}]}, {"pt6": [{"c": "ל", "l": 0}]}, {"pt7": [{"c": "ב", "l": 0}]}, {"pt8": [{"c": "כ", "l": 0}]}, {"pt9": [{"c": "ש", "l": 0}]}, {"pt10": [{"c": "כש", "l": 0}]}, {"pt11": [{"c": "בה", "l": 0}]}, {"pt12": [{"c": "וב", "l": 0}]}, {"pt13": [{"c": "וכ", "l": 0}]}, {"pt14": [{"c": "ול", "l": 0}]}, {"pt15": [{"c": "ומ", "l": 0}]}, {"pt16": [{"c": "וש", "l": 0}]}, {"pt17": [{"c": "הב", "l": 0}]}, {"pt18": [{"c": "הכ", "l": 0}]}, {"pt19": [{"c": "הל", "l": 0}]}, {"pt20": [{"c": "המ", "l": 0}]}, {"pt21": [{"c": "הש", "l": 0}]}, {"pt22": [{"c": "מה", "l": 0}]}, {"pt23": [{"c": "שה", "l": 0}]}, {"pt24": [{"c": "כל", "l": 0}]}]}'),e.execArray=["cleanWord","removeDiacritics","removeStopWords","normalizeHebrewCharacters"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHebrewCharacters=function(){return e.word=e.word.replace("ך","כ"),e.word=e.word.replace("ם","מ"),e.word=e.word.replace("ן","נ"),e.word=e.word.replace("ף","פ"),e.word=e.word.replace("ץ","צ"),!1},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}}(),e.Pipeline.registerFunction(e.he.stemmer,"stemmer-he"),e.he.stopWordFilter=e.generateStopWordFilter("אבל או אולי אותו אותי אותך אותם אותן אותנו אז אחר אחרות אחרי אחריכן אחרים אחרת אי איזה איך אין איפה אל אלה אלו אם אנחנו אני אף אפשר את אתה אתכם אתכן אתם אתן באיזה באיזו בגלל בין בלבד בעבור בעזרת בכל בכן בלי במידה במקום שבו ברוב בשביל בשעה ש בתוך גם דרך הוא היא היה היי היכן היתה היתי הם הן הנה הסיבה שבגללה הרי ואילו ואת זאת זה זות יהיה יוכל יוכלו יותר מדי יכול יכולה יכולות יכולים יכל יכלה יכלו יש כאן כאשר כולם כולן כזה כי כיצד כך כל כלל כמו כן כפי כש לא לאו לאיזותך לאן לבין לה להיות להם להן לו לזה לזות לי לך לכם לכן למה למעלה למעלה מ למטה למטה מ למעט למקום שבו למרות לנו לעבר לעיכן לפיכך לפני מאד מאחורי מאיזו סיבה מאין מאיפה מבלי מבעד מדוע מה מהיכן מול מחוץ מי מידע מכאן מכל מכן מלבד מן מנין מסוגל מעט מעטים מעל מצד מקום בו מתחת מתי נגד נגר נו עד עז על עלי עליו עליה עליהם עליך עלינו עם עצמה עצמהם עצמהן עצמו עצמי עצמם עצמן עצמנו פה רק שוב של שלה שלהם שלהן שלו שלי שלך שלכה שלכם שלכן שלנו שם תהיה תחת".split(" ")),e.Pipeline.registerFunction(e.he.stopWordFilter,"stopWordFilter-he")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hi.min.js b/assets/javascripts/lunr/min/lunr.hi.min.js new file mode 100644 index 000000000..7dbc41402 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hu.min.js b/assets/javascripts/lunr/min/lunr.hu.min.js new file mode 100644 index 000000000..ed9d909f7 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hu.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Hungarian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hy.min.js b/assets/javascripts/lunr/min/lunr.hy.min.js new file mode 100644 index 000000000..b37f79298 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hy.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.it.min.js b/assets/javascripts/lunr/min/lunr.it.min.js new file mode 100644 index 000000000..344b6a3c0 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.it.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Italian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ja.min.js b/assets/javascripts/lunr/min/lunr.ja.min.js new file mode 100644 index 000000000..5f254ebe9 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ja.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.no.min.js b/assets/javascripts/lunr/min/lunr.no.min.js new file mode 100644 index 000000000..92bc7e4e8 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.no.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Norwegian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.pt.min.js b/assets/javascripts/lunr/min/lunr.pt.min.js new file mode 100644 index 000000000..6c16996d6 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.pt.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Portuguese` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ro.min.js b/assets/javascripts/lunr/min/lunr.ro.min.js new file mode 100644 index 000000000..727714018 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ro.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Romanian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ru.min.js b/assets/javascripts/lunr/min/lunr.ru.min.js new file mode 100644 index 000000000..186cc485c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ru.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Russian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.sv.min.js b/assets/javascripts/lunr/min/lunr.sv.min.js new file mode 100644 index 000000000..3e5eb6400 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.sv.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Swedish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ta.min.js b/assets/javascripts/lunr/min/lunr.ta.min.js new file mode 100644 index 000000000..a644bed22 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ta.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.te.min.js b/assets/javascripts/lunr/min/lunr.te.min.js new file mode 100644 index 000000000..9fa7a93b9 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.te.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.te=function(){this.pipeline.reset(),this.pipeline.add(e.te.trimmer,e.te.stopWordFilter,e.te.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.te.stemmer))},e.te.wordCharacters="ఀ-ఄఅ-ఔక-హా-ౌౕ-ౖౘ-ౚౠ-ౡౢ-ౣ౦-౯౸-౿఼ఽ్ౝ౷౤౥",e.te.trimmer=e.trimmerSupport.generateTrimmer(e.te.wordCharacters),e.Pipeline.registerFunction(e.te.trimmer,"trimmer-te"),e.te.stopWordFilter=e.generateStopWordFilter("అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం".split(" ")),e.te.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.te.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.te.stemmer,"stemmer-te"),e.Pipeline.registerFunction(e.te.stopWordFilter,"stopWordFilter-te")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.th.min.js b/assets/javascripts/lunr/min/lunr.th.min.js new file mode 100644 index 000000000..dee3aac6e --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.th.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.tr.min.js b/assets/javascripts/lunr/min/lunr.tr.min.js new file mode 100644 index 000000000..563f6ec1f --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.tr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Turkish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=function(){var i=r.stemmerSupport.Among,e=r.stemmerSupport.SnowballProgram,n=new function(){function r(r,i,e){for(;;){var n=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(r,i,e)){Dr.cursor=Dr.limit-n;break}if(Dr.cursor=Dr.limit-n,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function n(){var i,e;i=Dr.limit-Dr.cursor,r(Wr,97,305);for(var n=0;nDr.limit_backward&&(Dr.cursor--,e=Dr.limit-Dr.cursor,i()))?(Dr.cursor=Dr.limit-e,!0):(Dr.cursor=Dr.limit-n,r()?(Dr.cursor=Dr.limit-n,!1):(Dr.cursor=Dr.limit-n,!(Dr.cursor<=Dr.limit_backward)&&(Dr.cursor--,!!i()&&(Dr.cursor=Dr.limit-n,!0))))}function u(r){return t(r,function(){return Dr.in_grouping_b(Wr,97,305)})}function o(){return u(function(){return Dr.eq_s_b(1,"n")})}function s(){return u(function(){return Dr.eq_s_b(1,"s")})}function c(){return u(function(){return Dr.eq_s_b(1,"y")})}function l(){return t(function(){return Dr.in_grouping_b(Lr,105,305)},function(){return Dr.out_grouping_b(Wr,97,305)})}function a(){return Dr.find_among_b(ur,10)&&l()}function m(){return n()&&Dr.in_grouping_b(Lr,105,305)&&s()}function d(){return Dr.find_among_b(or,2)}function f(){return n()&&Dr.in_grouping_b(Lr,105,305)&&c()}function b(){return n()&&Dr.find_among_b(sr,4)}function w(){return n()&&Dr.find_among_b(cr,4)&&o()}function _(){return n()&&Dr.find_among_b(lr,2)&&c()}function k(){return n()&&Dr.find_among_b(ar,2)}function p(){return n()&&Dr.find_among_b(mr,4)}function g(){return n()&&Dr.find_among_b(dr,2)}function y(){return n()&&Dr.find_among_b(fr,4)}function z(){return n()&&Dr.find_among_b(br,2)}function v(){return n()&&Dr.find_among_b(wr,2)&&c()}function h(){return Dr.eq_s_b(2,"ki")}function q(){return n()&&Dr.find_among_b(_r,2)&&o()}function C(){return n()&&Dr.find_among_b(kr,4)&&c()}function P(){return n()&&Dr.find_among_b(pr,4)}function F(){return n()&&Dr.find_among_b(gr,4)&&c()}function S(){return Dr.find_among_b(yr,4)}function W(){return n()&&Dr.find_among_b(zr,2)}function L(){return n()&&Dr.find_among_b(vr,4)}function x(){return n()&&Dr.find_among_b(hr,8)}function A(){return Dr.find_among_b(qr,2)}function E(){return n()&&Dr.find_among_b(Cr,32)&&c()}function j(){return Dr.find_among_b(Pr,8)&&c()}function T(){return n()&&Dr.find_among_b(Fr,4)&&c()}function Z(){return Dr.eq_s_b(3,"ken")&&c()}function B(){var r=Dr.limit-Dr.cursor;return!(T()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,Z()))))}function D(){if(A()){var r=Dr.limit-Dr.cursor;if(S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T())return!1}return!0}function G(){if(W()){Dr.bra=Dr.cursor,Dr.slice_del();var r=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,x()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,T()||(Dr.cursor=Dr.limit-r)))),nr=!1,!1}return!0}function H(){if(!L())return!0;var r=Dr.limit-Dr.cursor;return!E()&&(Dr.cursor=Dr.limit-r,!j())}function I(){var r,i=Dr.limit-Dr.cursor;return!(S()||(Dr.cursor=Dr.limit-i,F()||(Dr.cursor=Dr.limit-i,P()||(Dr.cursor=Dr.limit-i,C()))))||(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,T()||(Dr.cursor=Dr.limit-r),!1)}function J(){var r,i=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,nr=!0,B()&&(Dr.cursor=Dr.limit-i,D()&&(Dr.cursor=Dr.limit-i,G()&&(Dr.cursor=Dr.limit-i,H()&&(Dr.cursor=Dr.limit-i,I()))))){if(Dr.cursor=Dr.limit-i,!x())return;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T()||(Dr.cursor=Dr.limit-r)}Dr.bra=Dr.cursor,Dr.slice_del()}function K(){var r,i,e,n;if(Dr.ket=Dr.cursor,h()){if(r=Dr.limit-Dr.cursor,p())return Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,a()&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))),!0;if(Dr.cursor=Dr.limit-r,w()){if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,e=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-e,!m()&&(Dr.cursor=Dr.limit-e,!K())))return!0;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}return!0}if(Dr.cursor=Dr.limit-r,g()){if(n=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-n,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-n,!K())return!1;return!0}}return!1}function M(r){if(Dr.ket=Dr.cursor,!g()&&(Dr.cursor=Dr.limit-r,!k()))return!1;var i=Dr.limit-Dr.cursor;if(d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-i,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-i,!K())return!1;return!0}function N(r){if(Dr.ket=Dr.cursor,!z()&&(Dr.cursor=Dr.limit-r,!b()))return!1;var i=Dr.limit-Dr.cursor;return!(!m()&&(Dr.cursor=Dr.limit-i,!d()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)}function O(){var r,i=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,!(!w()&&(Dr.cursor=Dr.limit-i,!v()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,!(!W()||(Dr.bra=Dr.cursor,Dr.slice_del(),!K()))||(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!(a()||(Dr.cursor=Dr.limit-r,m()||(Dr.cursor=Dr.limit-r,K())))||(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)))}function Q(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,!p()&&(Dr.cursor=Dr.limit-e,!f()&&(Dr.cursor=Dr.limit-e,!_())))return!1;if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,a())Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()||(Dr.cursor=Dr.limit-i);else if(Dr.cursor=Dr.limit-r,!W())return!0;return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,K(),!0}function R(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,W())return Dr.bra=Dr.cursor,Dr.slice_del(),void K();if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,q())if(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-r,!m())){if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!W())return;if(Dr.bra=Dr.cursor,Dr.slice_del(),!K())return}Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}else if(Dr.cursor=Dr.limit-e,!M(e)&&(Dr.cursor=Dr.limit-e,!N(e))){if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,y())return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,i=Dr.limit-Dr.cursor,void(a()?(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())):(Dr.cursor=Dr.limit-i,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,K())));if(Dr.cursor=Dr.limit-e,!O()){if(Dr.cursor=Dr.limit-e,d())return Dr.bra=Dr.cursor,void Dr.slice_del();Dr.cursor=Dr.limit-e,K()||(Dr.cursor=Dr.limit-e,Q()||(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,(a()||(Dr.cursor=Dr.limit-e,m()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))))}}}function U(){var r;if(Dr.ket=Dr.cursor,r=Dr.find_among_b(Sr,4))switch(Dr.bra=Dr.cursor,r){case 1:Dr.slice_from("p");break;case 2:Dr.slice_from("ç");break;case 3:Dr.slice_from("t");break;case 4:Dr.slice_from("k")}}function V(){for(;;){var r=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(Wr,97,305)){Dr.cursor=Dr.limit-r;break}if(Dr.cursor=Dr.limit-r,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function X(r,i,e){if(Dr.cursor=Dr.limit-r,V()){var n=Dr.limit-Dr.cursor;if(!Dr.eq_s_b(1,i)&&(Dr.cursor=Dr.limit-n,!Dr.eq_s_b(1,e)))return!0;Dr.cursor=Dr.limit-r;var t=Dr.cursor;return Dr.insert(Dr.cursor,Dr.cursor,e),Dr.cursor=t,!1}return!0}function Y(){var r=Dr.limit-Dr.cursor;(Dr.eq_s_b(1,"d")||(Dr.cursor=Dr.limit-r,Dr.eq_s_b(1,"g")))&&X(r,"a","ı")&&X(r,"e","i")&&X(r,"o","u")&&X(r,"ö","ü")}function $(){for(var r,i=Dr.cursor,e=2;;){for(r=Dr.cursor;!Dr.in_grouping(Wr,97,305);){if(Dr.cursor>=Dr.limit)return Dr.cursor=r,!(e>0)&&(Dr.cursor=i,!0);Dr.cursor++}e--}}function rr(r,i,e){for(;!Dr.eq_s(i,e);){if(Dr.cursor>=Dr.limit)return!0;Dr.cursor++}return(tr=i)!=Dr.limit||(Dr.cursor=r,!1)}function ir(){var r=Dr.cursor;return!rr(r,2,"ad")||(Dr.cursor=r,!rr(r,5,"soyad"))}function er(){var r=Dr.cursor;return!ir()&&(Dr.limit_backward=r,Dr.cursor=Dr.limit,Y(),Dr.cursor=Dr.limit,U(),!0)}var nr,tr,ur=[new i("m",-1,-1),new i("n",-1,-1),new i("miz",-1,-1),new i("niz",-1,-1),new i("muz",-1,-1),new i("nuz",-1,-1),new i("müz",-1,-1),new i("nüz",-1,-1),new i("mız",-1,-1),new i("nız",-1,-1)],or=[new i("leri",-1,-1),new i("ları",-1,-1)],sr=[new i("ni",-1,-1),new i("nu",-1,-1),new i("nü",-1,-1),new i("nı",-1,-1)],cr=[new i("in",-1,-1),new i("un",-1,-1),new i("ün",-1,-1),new i("ın",-1,-1)],lr=[new i("a",-1,-1),new i("e",-1,-1)],ar=[new i("na",-1,-1),new i("ne",-1,-1)],mr=[new i("da",-1,-1),new i("ta",-1,-1),new i("de",-1,-1),new i("te",-1,-1)],dr=[new i("nda",-1,-1),new i("nde",-1,-1)],fr=[new i("dan",-1,-1),new i("tan",-1,-1),new i("den",-1,-1),new i("ten",-1,-1)],br=[new i("ndan",-1,-1),new i("nden",-1,-1)],wr=[new i("la",-1,-1),new i("le",-1,-1)],_r=[new i("ca",-1,-1),new i("ce",-1,-1)],kr=[new i("im",-1,-1),new i("um",-1,-1),new i("üm",-1,-1),new i("ım",-1,-1)],pr=[new i("sin",-1,-1),new i("sun",-1,-1),new i("sün",-1,-1),new i("sın",-1,-1)],gr=[new i("iz",-1,-1),new i("uz",-1,-1),new i("üz",-1,-1),new i("ız",-1,-1)],yr=[new i("siniz",-1,-1),new i("sunuz",-1,-1),new i("sünüz",-1,-1),new i("sınız",-1,-1)],zr=[new i("lar",-1,-1),new i("ler",-1,-1)],vr=[new i("niz",-1,-1),new i("nuz",-1,-1),new i("nüz",-1,-1),new i("nız",-1,-1)],hr=[new i("dir",-1,-1),new i("tir",-1,-1),new i("dur",-1,-1),new i("tur",-1,-1),new i("dür",-1,-1),new i("tür",-1,-1),new i("dır",-1,-1),new i("tır",-1,-1)],qr=[new i("casına",-1,-1),new i("cesine",-1,-1)],Cr=[new i("di",-1,-1),new i("ti",-1,-1),new i("dik",-1,-1),new i("tik",-1,-1),new i("duk",-1,-1),new i("tuk",-1,-1),new i("dük",-1,-1),new i("tük",-1,-1),new i("dık",-1,-1),new i("tık",-1,-1),new i("dim",-1,-1),new i("tim",-1,-1),new i("dum",-1,-1),new i("tum",-1,-1),new i("düm",-1,-1),new i("tüm",-1,-1),new i("dım",-1,-1),new i("tım",-1,-1),new i("din",-1,-1),new i("tin",-1,-1),new i("dun",-1,-1),new i("tun",-1,-1),new i("dün",-1,-1),new i("tün",-1,-1),new i("dın",-1,-1),new i("tın",-1,-1),new i("du",-1,-1),new i("tu",-1,-1),new i("dü",-1,-1),new i("tü",-1,-1),new i("dı",-1,-1),new i("tı",-1,-1)],Pr=[new i("sa",-1,-1),new i("se",-1,-1),new i("sak",-1,-1),new i("sek",-1,-1),new i("sam",-1,-1),new i("sem",-1,-1),new i("san",-1,-1),new i("sen",-1,-1)],Fr=[new i("miş",-1,-1),new i("muş",-1,-1),new i("müş",-1,-1),new i("mış",-1,-1)],Sr=[new i("b",-1,1),new i("c",-1,2),new i("d",-1,3),new i("ğ",-1,4)],Wr=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],Lr=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],xr=[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],Ar=[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],Er=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],jr=[17],Tr=[65],Zr=[65],Br=[["a",xr,97,305],["e",Ar,101,252],["ı",Er,97,305],["i",jr,101,105],["o",Tr,111,117],["ö",Zr,246,252],["u",Tr,111,117]],Dr=new e;this.setCurrent=function(r){Dr.setCurrent(r)},this.getCurrent=function(){return Dr.getCurrent()},this.stem=function(){return!!($()&&(Dr.limit_backward=Dr.cursor,Dr.cursor=Dr.limit,J(),Dr.cursor=Dr.limit,nr&&(R(),Dr.cursor=Dr.limit_backward,er())))}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.tr.stemmer,"stemmer-tr"),r.tr.stopWordFilter=r.generateStopWordFilter("acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle".split(" ")),r.Pipeline.registerFunction(r.tr.stopWordFilter,"stopWordFilter-tr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.vi.min.js b/assets/javascripts/lunr/min/lunr.vi.min.js new file mode 100644 index 000000000..22aed28c4 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.vi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.zh.min.js b/assets/javascripts/lunr/min/lunr.zh.min.js new file mode 100644 index 000000000..fda66e9c5 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.zh.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/tinyseg.js b/assets/javascripts/lunr/tinyseg.js new file mode 100644 index 000000000..167fa6dd6 --- /dev/null +++ b/assets/javascripts/lunr/tinyseg.js @@ -0,0 +1,206 @@ +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + + return function(lunr) { + // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript + // (c) 2008 Taku Kudo + // TinySegmenter is freely distributable under the terms of a new BSD licence. + // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt + + function TinySegmenter() { + var patterns = { + "[一二三四五六七八九十百千万億兆]":"M", + "[一-龠々〆ヵヶ]":"H", + "[ぁ-ん]":"I", + "[ァ-ヴーア-ン゙ー]":"K", + "[a-zA-Za-zA-Z]":"A", + "[0-90-9]":"N" + } + this.chartype_ = []; + for (var i in patterns) { + var regexp = new RegExp(i); + this.chartype_.push([regexp, patterns[i]]); + } + + this.BIAS__ = -332 + this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378}; + this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920}; + this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266}; + this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352}; + this.BP2__ = {"BO":60,"OO":-1762}; + this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965}; + this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146}; + this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699}; + this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973}; + this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682}; + this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669}; + this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990}; + this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832}; + this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649}; + this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393}; + this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841}; + this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68}; + this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591}; + this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685}; + this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156}; + this.TW1__ = {"につい":-4681,"東京都":2026}; + this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216}; + this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287}; + this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865}; + this.UC1__ = {"A":484,"K":93,"M":645,"O":-505}; + this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646}; + this.UC3__ = {"A":-1370,"I":2311}; + this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646}; + this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831}; + this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387}; + this.UP1__ = {"O":-214}; + this.UP2__ = {"B":69,"O":935}; + this.UP3__ = {"B":189}; + this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422}; + this.UQ2__ = {"BH":216,"BI":113,"OK":1759}; + this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212}; + this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135}; + this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568}; + this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278}; + this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637}; + this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343}; + this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496}; + + return this; + } + TinySegmenter.prototype.ctype_ = function(str) { + for (var i in this.chartype_) { + if (str.match(this.chartype_[i][0])) { + return this.chartype_[i][1]; + } + } + return "O"; + } + + TinySegmenter.prototype.ts_ = function(v) { + if (v) { return v; } + return 0; + } + + TinySegmenter.prototype.segment = function(input) { + if (input == null || input == undefined || input == "") { + return []; + } + var result = []; + var seg = ["B3","B2","B1"]; + var ctype = ["O","O","O"]; + var o = input.split(""); + for (i = 0; i < o.length; ++i) { + seg.push(o[i]); + ctype.push(this.ctype_(o[i])) + } + seg.push("E1"); + seg.push("E2"); + seg.push("E3"); + ctype.push("O"); + ctype.push("O"); + ctype.push("O"); + var word = seg[3]; + var p1 = "U"; + var p2 = "U"; + var p3 = "U"; + for (var i = 4; i < seg.length - 3; ++i) { + var score = this.BIAS__; + var w1 = seg[i-3]; + var w2 = seg[i-2]; + var w3 = seg[i-1]; + var w4 = seg[i]; + var w5 = seg[i+1]; + var w6 = seg[i+2]; + var c1 = ctype[i-3]; + var c2 = ctype[i-2]; + var c3 = ctype[i-1]; + var c4 = ctype[i]; + var c5 = ctype[i+1]; + var c6 = ctype[i+2]; + score += this.ts_(this.UP1__[p1]); + score += this.ts_(this.UP2__[p2]); + score += this.ts_(this.UP3__[p3]); + score += this.ts_(this.BP1__[p1 + p2]); + score += this.ts_(this.BP2__[p2 + p3]); + score += this.ts_(this.UW1__[w1]); + score += this.ts_(this.UW2__[w2]); + score += this.ts_(this.UW3__[w3]); + score += this.ts_(this.UW4__[w4]); + score += this.ts_(this.UW5__[w5]); + score += this.ts_(this.UW6__[w6]); + score += this.ts_(this.BW1__[w2 + w3]); + score += this.ts_(this.BW2__[w3 + w4]); + score += this.ts_(this.BW3__[w4 + w5]); + score += this.ts_(this.TW1__[w1 + w2 + w3]); + score += this.ts_(this.TW2__[w2 + w3 + w4]); + score += this.ts_(this.TW3__[w3 + w4 + w5]); + score += this.ts_(this.TW4__[w4 + w5 + w6]); + score += this.ts_(this.UC1__[c1]); + score += this.ts_(this.UC2__[c2]); + score += this.ts_(this.UC3__[c3]); + score += this.ts_(this.UC4__[c4]); + score += this.ts_(this.UC5__[c5]); + score += this.ts_(this.UC6__[c6]); + score += this.ts_(this.BC1__[c2 + c3]); + score += this.ts_(this.BC2__[c3 + c4]); + score += this.ts_(this.BC3__[c4 + c5]); + score += this.ts_(this.TC1__[c1 + c2 + c3]); + score += this.ts_(this.TC2__[c2 + c3 + c4]); + score += this.ts_(this.TC3__[c3 + c4 + c5]); + score += this.ts_(this.TC4__[c4 + c5 + c6]); + // score += this.ts_(this.TC5__[c4 + c5 + c6]); + score += this.ts_(this.UQ1__[p1 + c1]); + score += this.ts_(this.UQ2__[p2 + c2]); + score += this.ts_(this.UQ3__[p3 + c3]); + score += this.ts_(this.BQ1__[p2 + c2 + c3]); + score += this.ts_(this.BQ2__[p2 + c3 + c4]); + score += this.ts_(this.BQ3__[p3 + c2 + c3]); + score += this.ts_(this.BQ4__[p3 + c3 + c4]); + score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]); + score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]); + score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]); + score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]); + var p = "O"; + if (score > 0) { + result.push(word); + word = ""; + p = "B"; + } + p1 = p2; + p2 = p3; + p3 = p; + word += seg[i]; + } + result.push(word); + + return result; + } + + lunr.TinySegmenter = TinySegmenter; + }; + +})); \ No newline at end of file diff --git a/assets/javascripts/lunr/wordcut.js b/assets/javascripts/lunr/wordcut.js new file mode 100644 index 000000000..0d898c9ed --- /dev/null +++ b/assets/javascripts/lunr/wordcut.js @@ -0,0 +1,6708 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; + }) + this.addWords(words, false) + } + if(finalize){ + this.finalizeDict(); + } + }, + + dictSeek: function (l, r, ch, strOffset, pos) { + var ans = null; + while (l <= r) { + var m = Math.floor((l + r) / 2), + dict_item = this.dict[m], + len = dict_item.length; + if (len <= strOffset) { + l = m + 1; + } else { + var ch_ = dict_item[strOffset]; + if (ch_ < ch) { + l = m + 1; + } else if (ch_ > ch) { + r = m - 1; + } else { + ans = m; + if (pos == LEFT) { + r = m - 1; + } else { + l = m + 1; + } + } + } + } + return ans; + }, + + isFinal: function (acceptor) { + return this.dict[acceptor.l].length == acceptor.strOffset; + }, + + createAcceptor: function () { + return { + l: 0, + r: this.dict.length - 1, + strOffset: 0, + isFinal: false, + dict: this, + transit: function (ch) { + return this.dict.transit(this, ch); + }, + isError: false, + tag: "DICT", + w: 1, + type: "DICT" + }; + }, + + transit: function (acceptor, ch) { + var l = this.dictSeek(acceptor.l, + acceptor.r, + ch, + acceptor.strOffset, + LEFT); + if (l !== null) { + var r = this.dictSeek(l, + acceptor.r, + ch, + acceptor.strOffset, + RIGHT); + acceptor.l = l; + acceptor.r = r; + acceptor.strOffset++; + acceptor.isFinal = this.isFinal(acceptor); + } else { + acceptor.isError = true; + } + return acceptor; + }, + + sortuniq: function(a){ + return a.sort().filter(function(item, pos, arr){ + return !pos || item != arr[pos - 1]; + }) + }, + + flatten: function(a){ + //[[1,2],[3]] -> [1,2,3] + return [].concat.apply([], a); + } +}; +module.exports = WordcutDict; + +}).call(this,"/dist/tmp") +},{"glob":16,"path":22}],3:[function(require,module,exports){ +var WordRule = { + createAcceptor: function(tag) { + if (tag["WORD_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + var lch = ch.toLowerCase(); + if (lch >= "a" && lch <= "z") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "WORD_RULE", + type: "WORD_RULE", + w: 1}; + } +}; + +var NumberRule = { + createAcceptor: function(tag) { + if (tag["NUMBER_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch >= "0" && ch <= "9") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "NUMBER_RULE", + type: "NUMBER_RULE", + w: 1}; + } +}; + +var SpaceRule = { + tag: "SPACE_RULE", + createAcceptor: function(tag) { + + if (tag["SPACE_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch == " " || ch == "\t" || ch == "\r" || ch == "\n" || + ch == "\u00A0" || ch=="\u2003"//nbsp and emsp + ) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: SpaceRule.tag, + w: 1, + type: "SPACE_RULE"}; + } +} + +var SingleSymbolRule = { + tag: "SINSYM", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "SINSYM", + w: 1, + type: "SINSYM"}; + } +} + + +var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule]; + +module.exports = LatinRules; + +},{}],4:[function(require,module,exports){ +var _ = require("underscore") + , WordcutCore = require("./wordcut_core"); +var PathInfoBuilder = { + + /* + buildByPartAcceptors: function(path, acceptors, i) { + var + var genInfos = partAcceptors.reduce(function(genInfos, acceptor) { + + }, []); + + return genInfos; + } + */ + + buildByAcceptors: function(path, finalAcceptors, i) { + var self = this; + var infos = finalAcceptors.map(function(acceptor) { + var p = i - acceptor.strOffset + 1 + , _info = path[p]; + + var info = {p: p, + mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw), + w: acceptor.w + _info.w, + unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, + type: acceptor.type}; + + if (acceptor.type == "PART") { + for(var j = p + 1; j <= i; j++) { + path[j].merge = p; + } + info.merge = p; + } + + return info; + }); + return infos.filter(function(info) { return info; }); + }, + + fallback: function(path, leftBoundary, text, i) { + var _info = path[leftBoundary]; + if (text[i].match(/[\u0E48-\u0E4E]/)) { + if (leftBoundary != 0) + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + mw: 0, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; +/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") { + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; */ + } else { + return {p: leftBoundary, + mw: _info.mw, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; + } + }, + + build: function(path, finalAcceptors, i, leftBoundary, text) { + var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i); + if (basicPathInfos.length > 0) { + return basicPathInfos; + } else { + return [this.fallback(path, leftBoundary, text, i)]; + } + } +}; + +module.exports = function() { + return _.clone(PathInfoBuilder); +} + +},{"./wordcut_core":8,"underscore":25}],5:[function(require,module,exports){ +var _ = require("underscore"); + + +var PathSelector = { + selectPath: function(paths) { + var path = paths.reduce(function(selectedPath, path) { + if (selectedPath == null) { + return path; + } else { + if (path.unk < selectedPath.unk) + return path; + if (path.unk == selectedPath.unk) { + if (path.mw < selectedPath.mw) + return path + if (path.mw == selectedPath.mw) { + if (path.w < selectedPath.w) + return path; + } + } + return selectedPath; + } + }, null); + return path; + }, + + createPath: function() { + return [{p:null, w:0, unk:0, type: "INIT", mw:0}]; + } +}; + +module.exports = function() { + return _.clone(PathSelector); +}; + +},{"underscore":25}],6:[function(require,module,exports){ +function isMatch(pat, offset, ch) { + if (pat.length <= offset) + return false; + var _ch = pat[offset]; + return _ch == ch || + (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/)); +} + +var Rule0 = { + pat: "เหก็ม", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (isMatch(Rule0.pat, this.strOffset,ch)) { + this.isFinal = (this.strOffset + 1 == Rule0.pat.length); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "THAI_RULE", + type: "THAI_RULE", + w: 1}; + } +}; + +var PartRule = { + createAcceptor: function(tag) { + return {strOffset: 0, + patterns: [ + "แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก" + ], + isFinal: false, + transit: function(ch) { + var offset = this.strOffset; + this.patterns = this.patterns.filter(function(pat) { + return isMatch(pat, offset, ch); + }); + + if (this.patterns.length > 0) { + var len = 1 + offset; + this.isFinal = this.patterns.some(function(pat) { + return pat.length == len; + }); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "PART", + type: "PART", + unk: 1, + w: 1}; + } +}; + +var ThaiRules = [Rule0, PartRule]; + +module.exports = ThaiRules; + +},{}],7:[function(require,module,exports){ +var sys = require("sys") + , WordcutDict = require("./dict") + , WordcutCore = require("./wordcut_core") + , PathInfoBuilder = require("./path_info_builder") + , PathSelector = require("./path_selector") + , Acceptors = require("./acceptors") + , latinRules = require("./latin_rules") + , thaiRules = require("./thai_rules") + , _ = require("underscore"); + + +var Wordcut = Object.create(WordcutCore); +Wordcut.defaultPathInfoBuilder = PathInfoBuilder; +Wordcut.defaultPathSelector = PathSelector; +Wordcut.defaultAcceptors = Acceptors; +Wordcut.defaultLatinRules = latinRules; +Wordcut.defaultThaiRules = thaiRules; +Wordcut.defaultDict = WordcutDict; + + +Wordcut.initNoDict = function(dict_path) { + var self = this; + self.pathInfoBuilder = new self.defaultPathInfoBuilder; + self.pathSelector = new self.defaultPathSelector; + self.acceptors = new self.defaultAcceptors; + self.defaultLatinRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); + self.defaultThaiRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); +}; + +Wordcut.init = function(dict_path, withDefault, additionalWords) { + withDefault = withDefault || false; + this.initNoDict(); + var dict = _.clone(this.defaultDict); + dict.init(dict_path, withDefault, additionalWords); + this.acceptors.creators.push(dict); +}; + +module.exports = Wordcut; + +},{"./acceptors":1,"./dict":2,"./latin_rules":3,"./path_info_builder":4,"./path_selector":5,"./thai_rules":6,"./wordcut_core":8,"sys":28,"underscore":25}],8:[function(require,module,exports){ +var WordcutCore = { + + buildPath: function(text) { + var self = this + , path = self.pathSelector.createPath() + , leftBoundary = 0; + self.acceptors.reset(); + for (var i = 0; i < text.length; i++) { + var ch = text[i]; + self.acceptors.transit(ch); + + var possiblePathInfos = self + .pathInfoBuilder + .build(path, + self.acceptors.getFinalAcceptors(), + i, + leftBoundary, + text); + var selectedPath = self.pathSelector.selectPath(possiblePathInfos) + + path.push(selectedPath); + if (selectedPath.type !== "UNK") { + leftBoundary = i; + } + } + return path; + }, + + pathToRanges: function(path) { + var e = path.length - 1 + , ranges = []; + + while (e > 0) { + var info = path[e] + , s = info.p; + + if (info.merge !== undefined && ranges.length > 0) { + var r = ranges[ranges.length - 1]; + r.s = info.merge; + s = r.s; + } else { + ranges.push({s:s, e:e}); + } + e = s; + } + return ranges.reverse(); + }, + + rangesToText: function(text, ranges, delimiter) { + return ranges.map(function(r) { + return text.substring(r.s, r.e); + }).join(delimiter); + }, + + cut: function(text, delimiter) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + return this + .rangesToText(text, ranges, + (delimiter === undefined ? "|" : delimiter)); + }, + + cutIntoRanges: function(text, noText) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + if (!noText) { + ranges.forEach(function(r) { + r.text = text.substring(r.s, r.e); + }); + } + return ranges; + }, + + cutIntoArray: function(text) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + return ranges.map(function(r) { + return text.substring(r.s, r.e) + }); + } +}; + +module.exports = WordcutCore; + +},{}],9:[function(require,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && !isFinite(value)) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) { + return a === b; + } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +},{"util/":28}],10:[function(require,module,exports){ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} + +},{}],11:[function(require,module,exports){ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + + +},{"balanced-match":10,"concat-map":13}],12:[function(require,module,exports){ + +},{}],13:[function(require,module,exports){ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +},{}],14:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],15:[function(require,module,exports){ +(function (process){ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern) + } + + return { + matcher: new Minimatch(pattern), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + // disable comments and negation unless the user explicitly + // passes in false as the option. + options.nonegate = options.nonegate === false ? false : true + options.nocomment = options.nocomment === false ? false : true + deprecationWarning(options) + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +// TODO(isaacs): remove entirely in v6 +// exported to reset in tests +exports.deprecationWarned +function deprecationWarning(options) { + if (!options.nonegate || !options.nocomment) { + if (process.noDeprecation !== true && !exports.deprecationWarned) { + var msg = 'glob WARNING: comments and negation will be disabled in v6' + if (process.throwDeprecation) + throw new Error(msg) + else if (process.traceDeprecation) + console.trace(msg) + else + console.error(msg) + + exports.deprecationWarned = true + } + } +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +}).call(this,require('_process')) +},{"_process":24,"minimatch":20,"path":22,"path-is-absolute":23}],16:[function(require,module,exports){ +(function (process){ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +glob.hasMagic = function (pattern, options_) { + var options = util._extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./sync.js":17,"_process":24,"assert":9,"events":14,"fs":12,"inflight":18,"inherits":19,"minimatch":20,"once":21,"path":22,"path-is-absolute":23,"util":28}],17:[function(require,module,exports){ +(function (process){ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./glob.js":16,"_process":24,"assert":9,"fs":12,"minimatch":20,"path":22,"path-is-absolute":23,"util":28}],18:[function(require,module,exports){ +(function (process){ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} + +}).call(this,require('_process')) +},{"_process":24,"once":21,"wrappy":29}],19:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],20:[function(require,module,exports){ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = require('path') +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + // "" only matches "" + if (pattern.trim() === '') return p === '' + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } + + // should be unreachable. + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} + +},{"brace-expansion":11,"path":22}],21:[function(require,module,exports){ +var wrappy = require('wrappy') +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + +},{"wrappy":29}],22:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":24}],23:[function(require,module,exports){ +(function (process){ +'use strict'; + +function posix(path) { + return path.charAt(0) === '/'; +} + +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} + +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; + +}).call(this,require('_process')) +},{"_process":24}],24:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],25:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],26:[function(require,module,exports){ +arguments[4][19][0].apply(exports,arguments) +},{"dup":19}],27:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],28:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":27,"_process":24,"inherits":26}],29:[function(require,module,exports){ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + +},{}]},{},[7])(7) +}); \ No newline at end of file diff --git a/assets/javascripts/workers/search.1e90e0fb.min.js b/assets/javascripts/workers/search.1e90e0fb.min.js new file mode 100644 index 000000000..ff43aeddd --- /dev/null +++ b/assets/javascripts/workers/search.1e90e0fb.min.js @@ -0,0 +1,2 @@ +"use strict";(()=>{var xe=Object.create;var G=Object.defineProperty,ve=Object.defineProperties,Se=Object.getOwnPropertyDescriptor,Te=Object.getOwnPropertyDescriptors,Qe=Object.getOwnPropertyNames,Y=Object.getOwnPropertySymbols,Ee=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Z=Math.pow,J=(t,e,r)=>e in t?G(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,_=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(Y)for(var r of Y(e))be.call(e,r)&&J(t,r,e[r]);return t},B=(t,e)=>ve(t,Te(e));var Le=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var we=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Qe(e))!X.call(t,i)&&i!==r&&G(t,i,{get:()=>e[i],enumerable:!(n=Se(e,i))||n.enumerable});return t};var Pe=(t,e,r)=>(r=t!=null?xe(Ee(t)):{},we(e||!t||!t.__esModule?G(r,"default",{value:t,enumerable:!0}):r,t));var W=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var te=Le((K,ee)=>{(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var f=t.utils.clone(r)||{};f.position=[a,c],f.index=s.length,s.push(new t.Token(n.slice(a,o),f))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?f+=2:a==u&&(r+=n[c+1]*i[f+1],c+=2,f+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var f=s.str.charAt(0),g=s.str.charAt(1),l;g in s.node.edges?l=s.node.edges[g]:(l=new t.TokenSet,s.node.edges[g]=l),s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:f+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof K=="object"?ee.exports=r():e.lunr=r()}(this,function(){return t})})()});var de=Pe(te());function re(t,e=document){let r=ke(t,e);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${t}" to be present`);return r}function ke(t,e=document){return e.querySelector(t)||void 0}Object.entries||(Object.entries=function(t){let e=[];for(let r of Object.keys(t))e.push([r,t[r]]);return e});Object.values||(Object.values=function(t){let e=[];for(let r of Object.keys(t))e.push(t[r]);return e});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(t,e){typeof t=="object"?(this.scrollLeft=t.left,this.scrollTop=t.top):(this.scrollLeft=t,this.scrollTop=e)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...t){let e=this.parentNode;if(e){t.length===0&&e.removeChild(this);for(let r=t.length-1;r>=0;r--){let n=t[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));function ne(t){let e=new Map;for(let r of t){let[n]=r.location.split("#"),i=e.get(n);typeof i=="undefined"?e.set(n,r):(e.set(r.location,r),r.parent=i)}return e}function H(t,e,r){var s;e=new RegExp(e,"g");let n,i=0;do{n=e.exec(t);let o=(s=n==null?void 0:n.index)!=null?s:t.length;if(in?e(r,1,n,n=i):t.charAt(i)===">"&&(t.charAt(n+1)==="/"?--s===0&&e(r++,2,n,i+1):t.charAt(i-1)!=="/"&&s++===0&&e(r,0,n,i+1),n=i+1);i>n&&e(r,1,n,i)}function se(t,e,r,n=!1){return q([t],e,r,n).pop()}function q(t,e,r,n=!1){let i=[0];for(let s=1;s>>2&1023,c=a[0]>>>12;i.push(+(u>c)+i[i.length-1])}return t.map((s,o)=>{let a=0,u=new Map;for(let f of r.sort((g,l)=>g-l)){let g=f&1048575,l=f>>>20;if(i[l]!==o)continue;let m=u.get(l);typeof m=="undefined"&&u.set(l,m=[]),m.push(g)}if(u.size===0)return s;let c=[];for(let[f,g]of u){let l=e[f],m=l[0]>>>12,x=l[l.length-1]>>>12,v=l[l.length-1]>>>2&1023;n&&m>a&&c.push(s.slice(a,m));let d=s.slice(m,x+v);for(let y of g.sort((b,E)=>E-b)){let b=(l[y]>>>12)-m,E=(l[y]>>>2&1023)+b;d=[d.slice(0,b),"",d.slice(b,E),"",d.slice(E)].join("")}if(a=x+v,c.push(d)===2)break}return n&&a{var f;switch(i[f=o+=s]||(i[f]=[]),a){case 0:case 2:i[o].push(u<<12|c-u<<2|a);break;case 1:let g=r[n].slice(u,c);H(g,lunr.tokenizer.separator,(l,m)=>{if(typeof lunr.segmenter!="undefined"){let x=g.slice(l,m);if(/^[MHIK]$/.test(lunr.segmenter.ctype_(x))){let v=lunr.segmenter.segment(x);for(let d=0,y=0;dr){return t.trim().split(/"([^"]+)"/g).map((r,n)=>n&1?r.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):r).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").split(/\s+/g).reduce((r,n)=>{let i=e(n);return[...r,...Array.isArray(i)?i:[i]]},[]).map(r=>/([~^]$)/.test(r)?`${r}1`:r).map(r=>/(^[+-]|[~^]\d+$)/.test(r)?r:`${r}*`).join(" ")}function ue(t){return ae(t,e=>{let r=[],n=new lunr.QueryLexer(e);n.run();for(let{type:i,str:s,start:o,end:a}of n.lexemes)switch(i){case"FIELD":["title","text","tags"].includes(s)||(e=[e.slice(0,a)," ",e.slice(a+1)].join(""));break;case"TERM":H(s,lunr.tokenizer.separator,(...u)=>{r.push([e.slice(0,o),s.slice(...u),e.slice(a)].join(""))})}return r})}function ce(t){let e=new lunr.Query(["title","text","tags"]);new lunr.QueryParser(t,e).parse();for(let n of e.clauses)n.usePipeline=!0,n.term.startsWith("*")&&(n.wildcard=lunr.Query.wildcard.LEADING,n.term=n.term.slice(1)),n.term.endsWith("*")&&(n.wildcard=lunr.Query.wildcard.TRAILING,n.term=n.term.slice(0,-1));return e.clauses}function le(t,e){var i;let r=new Set(t),n={};for(let s=0;s0;){let o=i[--s];for(let u=1;un[o]-u&&(r.add(t.slice(o,o+u)),i[s++]=o+u);let a=o+n[o];n[a]&&ar=>{if(typeof r[e]=="undefined")return;let n=[r.location,e].join(":");return t.set(n,lunr.tokenizer.table=[]),r[e]}}function Re(t,e){let[r,n]=[new Set(t),new Set(e)];return[...new Set([...r].filter(i=>!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){let i=Oe(this.table=new Map);this.map=ne(r),this.options=n,this.index=lunr(function(){this.metadataWhitelist=["position"],this.b(0),e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang)),this.tokenizer=oe,lunr.tokenizer.separator=new RegExp(e.separator),lunr.segmenter="TinySegmenter"in lunr?new lunr.TinySegmenter:void 0;let s=Re(["trimmer","stopWordFilter","stemmer"],e.pipeline);for(let o of e.lang.map(a=>a==="en"?lunr:lunr[a]))for(let a of s)this.pipeline.remove(o[a]),this.searchPipeline.remove(o[a]);this.ref("location");for(let[o,a]of Object.entries(e.fields))this.field(o,B(_({},a),{extractor:i(o)}));for(let o of r)this.add(o,{boost:o.boost})})}search(e){if(e=e.replace(new RegExp("\\p{sc=Han}+","gu"),s=>[...he(s,this.index.invertedIndex)].join("* ")),e=ue(e),!e)return{items:[]};let r=ce(e).filter(s=>s.presence!==lunr.Query.presence.PROHIBITED),n=this.index.search(e).reduce((s,{ref:o,score:a,matchData:u})=>{let c=this.map.get(o);if(typeof c!="undefined"){c=_({},c),c.tags&&(c.tags=[...c.tags]);let f=le(r,Object.keys(u.metadata));for(let l of this.index.fields){if(typeof c[l]=="undefined")continue;let m=[];for(let d of Object.values(u.metadata))typeof d[l]!="undefined"&&m.push(...d[l].position);if(!m.length)continue;let x=this.table.get([c.location,l].join(":")),v=Array.isArray(c[l])?q:se;c[l]=v(c[l],x,m,l!=="text")}let g=+!c.parent+Object.values(f).filter(l=>l).length/Object.keys(f).length;s.push(B(_({},c),{score:a*(1+Z(g,2)),terms:f}))}return s},[]).sort((s,o)=>o.score-s.score).reduce((s,o)=>{let a=this.map.get(o.location);if(typeof a!="undefined"){let u=a.parent?a.parent.location:a.location;s.set(u,[...s.get(u)||[],o])}return s},new Map);for(let[s,o]of n)if(!o.find(a=>a.location===s)){let a=this.map.get(s);o.push(B(_({},a),{score:0,terms:{}}))}let i;if(this.options.suggest){let s=this.index.query(o=>{for(let a of r)o.term(a.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});i=s.length?Object.keys(s[0].matchData.metadata):[]}return _({items:[...n.values()]},typeof i!="undefined"&&{suggest:i})}};var fe;function Ie(t){return W(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=re("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Fe(t){return W(this,null,function*(){switch(t.type){case 0:return yield Ie(t.data.config),fe=new U(t.data),{type:1};case 2:let e=t.data;try{return{type:3,data:fe.search(e)}}catch(r){return console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`),console.warn(r),{type:3,data:{items:[]}}}default:throw new TypeError("Invalid message type")}})}self.lunr=de.default;addEventListener("message",t=>W(void 0,null,function*(){postMessage(yield Fe(t.data))}));})(); diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 000000000..bd207c1e7 Binary files /dev/null and b/assets/logo.png differ diff --git a/assets/stylesheets/main.c0d16a3a.min.css b/assets/stylesheets/main.c0d16a3a.min.css new file mode 100644 index 000000000..344d70aa8 --- /dev/null +++ b/assets/stylesheets/main.c0d16a3a.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-bg-color--light:#f5f5f5b3;--md-code-bg-color--lighter:#f5f5f54d;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset a code{color:var(--md-typeset-a-color)}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none;transition:background-color 125ms}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;transition:color 125ms,background-color 125ms;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{cursor:help;text-decoration:none}.md-typeset [data-preview],.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light)}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block;margin:0 auto}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{border-radius:100%;display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{border-radius:100%;filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}:root{--md-code-select-icon:url('data:image/svg+xml;charset=utf-8,');--md-code-copy-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-code__content{display:grid}.md-code__nav{background-color:var(--md-code-bg-color--lighter);border-radius:.1rem;display:flex;gap:.2rem;padding:.2rem;position:absolute;right:.25em;top:.25em;transition:background-color .25s;z-index:1}:hover>.md-code__nav{background-color:var(--md-code-bg-color--light)}.md-code__button{color:var(--md-default-fg-color--lightest);cursor:pointer;display:block;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em}:hover>*>.md-code__button{color:var(--md-default-fg-color--light)}.md-code__button.focus-visible,.md-code__button:hover{color:var(--md-accent-fg-color)}.md-code__button--active{color:var(--md-default-fg-color)!important}.md-code__button:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-code__button[data-md-type=select]:after{-webkit-mask-image:var(--md-code-select-icon);mask-image:var(--md-code-select-icon)}.md-code__button[data-md-type=copy]:after{-webkit-mask-image:var(--md-code-copy-icon);mask-image:var(--md-code-copy-icon)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{display:flex;flex-wrap:wrap;place-content:baseline center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem;margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem;margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__link{align-items:flex-start;display:flex;gap:.4rem;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed,.md-nav__link--passed code{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}.md-nav__link .md-ellipsis code{word-break:normal}[dir=ltr] .md-nav__link .md-icon:last-child{margin-left:auto}[dir=rtl] .md-nav__link .md-icon:last-child{margin-right:auto}.md-nav__link .md-typeset{font-size:.7rem;line-height:1.3}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em}.md-nav__link[for]:focus,.md-nav__link[for]:hover,.md-nav__link[href]:focus,.md-nav__link[href]:hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link[for]:focus code,.md-nav__link[for]:hover code,.md-nav__link[href]:focus code,.md-nav__link[href]:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1;min-width:0}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.234375em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.984375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav{margin-bottom:-.4rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--secondary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--secondary .md-nav__list{padding-right:.6rem}.md-nav--secondary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--secondary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--secondary .md-nav__item>.md-nav__link{margin-left:.4rem}}@media screen and (min-width:76.25em){.md-nav{margin-bottom:-.4rem;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--primary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--primary .md-nav__list{padding-right:.6rem}.md-nav--primary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--primary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--primary .md-nav__item>.md-nav__link{margin-left:.4rem}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle.md-toggle--indeterminate~.md-nav,.md-nav__toggle:checked~.md-nav{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__toggle.md-toggle--indeterminate~.md-nav{transition:none}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-icon,.md-nav__item--section>.md-nav__link>[for]{display:none}[dir=ltr] .md-nav__item--section>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav__item--section>.md-nav{margin-right:-.6rem}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-toggle--indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);margin-top:0;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}[dir=ltr] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-left:-.6rem}[dir=rtl] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-right:-.6rem}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:1fr;opacity:1;visibility:visible}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}:root{--md-path-icon:url('data:image/svg+xml;charset=utf-8,')}.md-path{font-size:.7rem;margin:0 .8rem;overflow:auto;padding-top:1.2rem}.md-path:not([hidden]){display:block}@media screen and (min-width:76.25em){.md-path{margin:0 1.2rem}}.md-path__list{align-items:center;display:flex;gap:.2rem;list-style:none;margin:0;padding:0}.md-path__item:not(:first-child){display:inline-flex;gap:.2rem;white-space:nowrap}.md-path__item:not(:first-child):before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline;height:.8rem;-webkit-mask-image:var(--md-path-icon);mask-image:var(--md-path-icon);width:.8rem}.md-path__link{align-items:center;color:var(--md-default-fg-color--light);display:flex}.md-path__link:focus,.md-path__link:hover{color:var(--md-accent-fg-color)}:root{--md-post-pin-icon:url('data:image/svg+xml;charset=utf-8,')}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.234375em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem 1.2rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post__title{color:var(--md-default-fg-color--light);font-weight:700}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary{margin:1em 0}.md-pin{background:var(--md-default-fg-color--lightest);border-radius:1rem;margin-top:-.05rem;padding:.2rem}.md-pin:after{background-color:currentcolor;content:"";display:block;height:.6rem;margin:0 auto;-webkit-mask-image:var(--md-post-pin-icon);mask-image:var(--md-post-pin-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.6rem}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.234375em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.234375em){.md-sidebar.md-sidebar--post{padding:0;position:static;width:100%}.md-sidebar.md-sidebar--post .md-sidebar__scrollwrap{overflow:visible}.md-sidebar.md-sidebar--post .md-sidebar__inner{padding:0}.md-sidebar.md-sidebar--post .md-post__meta{margin-left:.6rem;margin-right:.6rem}.md-sidebar.md-sidebar--post .md-nav__item{border:none;display:inline}.md-sidebar.md-sidebar--post .md-nav__list{display:inline-flex;flex-wrap:wrap;gap:.6rem;padding-bottom:.6rem;padding-top:.6rem}.md-sidebar.md-sidebar--post .md-nav__link{padding:0}.md-sidebar.md-sidebar--post .md-nav{height:auto;margin-bottom:0;position:static}}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.234375em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.984375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:#0000}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>.md-icon{margin-left:.2rem}[dir=rtl] .md-search__options>.md-icon{margin-right:.2rem}.md-search__options>.md-icon{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>.md-icon:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.984375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:focus,.md-search-result__link:hover{background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:focus>div,.md-search-result__more>summary:hover>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.984375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.234375em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags:not([hidden]){display:inline-flex;flex-wrap:wrap;gap:.5em;margin-bottom:.75em;margin-top:-.125em}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-shadow{opacity:.5}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,')}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:xxx;list-style:none}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(xxx);counter-increment:xxx;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}:root{--md-tooltip-width:20rem;--md-tooltip-tail:0.3rem}.md-tooltip2{-webkit-backface-visibility:hidden;backface-visibility:hidden;color:var(--md-default-fg-color);font-family:var(--md-text-font-family);opacity:0;pointer-events:none;position:absolute;top:calc(var(--md-tooltip-host-y) + var(--md-tooltip-y));transform:translateY(-.4rem);transform-origin:calc(var(--md-tooltip-host-x) + var(--md-tooltip-x)) 0;transition:transform 0ms .25s,opacity .25s,z-index .25s;width:100%;z-index:0}.md-tooltip2:before{border-left:var(--md-tooltip-tail) solid #0000;border-right:var(--md-tooltip-tail) solid #0000;content:"";display:block;left:clamp(1.5 * .8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-tail),100vw - 2 * var(--md-tooltip-tail) - 1.5 * .8rem);position:absolute;z-index:1}.md-tooltip2--top:before{border-top:var(--md-tooltip-tail) solid var(--md-default-bg-color);bottom:calc(var(--md-tooltip-tail)*-1 + .025rem);filter:drop-shadow(0 1px 0 hsla(0,0%,0%,.05))}.md-tooltip2--bottom:before{border-bottom:var(--md-tooltip-tail) solid var(--md-default-bg-color);filter:drop-shadow(0 -1px 0 hsla(0,0%,0%,.05));top:calc(var(--md-tooltip-tail)*-1 + .025rem)}.md-tooltip2--active{opacity:1;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.5,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip2__inner{scrollbar-gutter:stable;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);left:clamp(.8rem,var(--md-tooltip-host-x) - .8rem,100vw - var(--md-tooltip-width) - .8rem);max-height:40vh;max-width:calc(100vw - 1.6rem);position:relative;scrollbar-width:thin}.md-tooltip2__inner::-webkit-scrollbar{height:.2rem;width:.2rem}.md-tooltip2__inner::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-tooltip2__inner::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}[role=dialog]>.md-tooltip2__inner{font-size:.64rem;overflow:auto;padding:0 .8rem;pointer-events:auto;width:var(--md-tooltip-width)}[role=dialog]>.md-tooltip2__inner:after,[role=dialog]>.md-tooltip2__inner:before{content:"";display:block;height:.8rem;position:sticky;width:100%;z-index:10}[role=dialog]>.md-tooltip2__inner:before{background:linear-gradient(var(--md-default-bg-color),#0000 75%);top:0}[role=dialog]>.md-tooltip2__inner:after{background:linear-gradient(#0000,var(--md-default-bg-color) 75%);bottom:0}[role=tooltip]>.md-tooltip2__inner{font-size:.5rem;font-weight:700;left:clamp(.8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-width)/2,100vw - var(--md-tooltip-width) - .8rem);max-width:min(100vw - 2 * .8rem,400px);padding:.2rem .4rem;-webkit-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.md-tooltip2__inner.md-typeset>:first-child{margin-top:0}.md-tooltip2__inner.md-typeset>:last-child{margin-bottom:0}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__alias{margin-left:.3rem;opacity:.7}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.075rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}.md-typeset div.arithmatex>*{width:min-content}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset div.arithmatex mjx-assistive-mml{height:0}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem;overflow:hidden}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying]{display:initial}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .linenodiv span[class]{padding-right:.5882352941em}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/assets/stylesheets/palette.ab4e12ef.min.css b/assets/stylesheets/palette.ab4e12ef.min.css new file mode 100644 index 000000000..75aaf8425 --- /dev/null +++ b/assets/stylesheets/palette.ab4e12ef.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-default-fg-color:hsla(var(--md-hue),15%,90%,0.82);--md-default-fg-color--light:hsla(var(--md-hue),15%,90%,0.56);--md-default-fg-color--lighter:hsla(var(--md-hue),15%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),15%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,14%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,14%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,14%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,14%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,0.82);--md-code-bg-color:hsla(var(--md-hue),15%,18%,1);--md-code-bg-color--light:hsla(var(--md-hue),15%,18%,0.9);--md-code-bg-color--lighter:hsla(var(--md-hue),15%,18%,0.54);--md-code-hl-color:#2977ff;--md-code-hl-color--light:#2977ff1a;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-kbd-color:hsla(var(--md-hue),15%,90%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,90%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-mark-color:#4287ff4d;--md-typeset-table-color:hsla(var(--md-hue),15%,95%,0.12);--md-typeset-table-color--light:hsla(var(--md-hue),15%,95%,0.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,10%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,8%,1);--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #00000040,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;color-scheme:dark}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#c46fd3}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a47bea}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#5488e8}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff764d}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c1775c}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5e8bde}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:hsla(var(--md-hue),0%,100%,1);--md-primary-fg-color--light:hsla(var(--md-hue),0%,100%,0.7);--md-primary-fg-color--dark:hsla(var(--md-hue),0%,0%,0.07);--md-primary-bg-color:hsla(var(--md-hue),0%,0%,0.87);--md-primary-bg-color--light:hsla(var(--md-hue),0%,0%,0.54);--md-typeset-a-color:#4051b5}[data-md-color-primary=white] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=white] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:hsla(var(--md-hue),0%,0%,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:hsla(var(--md-hue),0%,0%,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:hsla(var(--md-hue),0%,0%,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid #00000012}}[data-md-color-primary=black]{--md-primary-fg-color:hsla(var(--md-hue),15%,9%,1);--md-primary-fg-color--light:hsla(var(--md-hue),15%,9%,0.54);--md-primary-fg-color--dark:hsla(var(--md-hue),15%,9%,1);--md-primary-bg-color:hsla(var(--md-hue),15%,100%,1);--md-primary-bg-color--light:hsla(var(--md-hue),15%,100%,0.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=black] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}[data-md-color-primary=black] .md-header{background-color:hsla(var(--md-hue),15%,9%,1)}@media screen and (max-width:59.984375em){[data-md-color-primary=black] .md-nav__source{background-color:hsla(var(--md-hue),15%,11%,.87)}}@media screen and (max-width:76.234375em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:hsla(var(--md-hue),15%,9%,1)}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:hsla(var(--md-hue),15%,9%,1)}} \ No newline at end of file diff --git a/commands/index.html b/commands/index.html new file mode 100644 index 000000000..42394ddf1 --- /dev/null +++ b/commands/index.html @@ -0,0 +1,3307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Commands - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + + + +

Commands

+ +

Codeception commands provided by the library

+

The library provides some custom commands that can be added to the project Codeception configuration file ( +either codeception.yml or codeception.dist.yml).

+

run and codeception:run

+

Enable the commands with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\RunOriginal"
+    - "lucatume\\WPBrowser\\Command\\RunAll"
+
+

WordPress extensive use of global variables, constants and side effectes makes it difficult to run multiple test suites +in the same process without running into conflicts due to leaking state and side effects. +For this reason the project replaces Codeception run command with one that will run each suite in a separate process. +You can invoke the original Codeception command using the codeception:run command. +Just like the original, the run command accepts all the arguments and options of the original Codeception +command.

+

Run all the suites, each one in a separate process:

+
vendor/bin/codecept run
+
+

Run only the Integration suite:

+
vendor/bin/codecept run Integration
+
+

Run a specific test file:

+
vendor/bin/codecept run Integration tests/Integration/MyTest.php
+
+

Run a specific test method:

+
vendor/bin/codecept run Integration tests/Integration/MyTest.php:testMyMethod
+
+

Read the Codeception documentation for more information about the run command.

+

dev:start

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\DevStart"
+
+

If not already running, start the services required to run the tests. +The started services are read from the Codeception configuration file (either codeception.yml +or codeception.dist.yml), from the extensions section, under the config key.

+

Given the following configuration:

+
extensions:
+  enabled:
+    - lucatume\WPBrowser\Extension\ChromeDriverController
+    - lucatume\WPBrowser\Extension\BuiltInServerController
+    - lucatume\WPBrowser\Extension\DockerComposeController
+  config:
+    "lucatume\\WPBrowser\\Extension\\ChromeDriverController":
+      port: '%CHROMEDRIVER_PORT%'
+    "lucatume\\WPBrowser\\Extension\\BuiltInServerController":
+      docroot: '%WORDPRESS_ROOT_DIR%'
+      workers: 5
+      port: '%BUILT_IN_SERVER_PORT%'
+    "lucatume\\WPBrowser\\Extension\\DockerComposeController":
+      compose-file: 'tests/docker-compose.yml'
+      env-file: 'tests/.env'
+
+

Running the command will start ChromeDriver, the built-in PHP server and Docker Compose.

+

dev:stop

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\DevStop"
+
+

If running, stop the services required to run the tests. +The stopped services are read from the Codeception configuration file (either codeception.yml +or codeception.dist.yml), from the extensions section, under the config key.

+

Given the following configuration:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\ChromeDriverController"
+    - "lucatume\\WPBrowser\\Extension\\BuiltInServerController"
+    - "lucatume\\WPBrowser\\Extension\\DockerComposeController"
+  config:
+    "lucatume\\WPBrowser\\Extension\\ChromeDriverController":
+      port: '%CHROMEDRIVER_PORT%'
+    "lucatume\\WPBrowser\\Extension\\BuiltInServerController":
+      docroot: '%WORDPRESS_ROOT_DIR%'
+      workers: 5
+      port: '%BUILT_IN_SERVER_PORT%'
+    "lucatume\\WPBrowser\\Extension\\DockerComposeController":
+      compose-file: 'tests/docker-compose.yml'
+      env-file: 'tests/.env'
+
+

Running the command will stop ChromeDriver, the built-in PHP server and Docker Compose.

+

dev:restart

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\DevRestart"
+
+

This command is just a shortcut to run dev:stop and dev:start in sequence.

+

dev:info

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\DevInfo"
+
+

Provides information about the local testing stack managed by +the DockerComposeController, BuiltInServerController +and ChromeDriverController extensions.

+

wp:db:import

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\DbImport"
+
+

You can use WP CLI to interact with your WordPress installation, but WP CLI does not support SQLite databases in +the context of the wp db import command. +This command fills that gap by providing a database dump file import command that will support MySQL and SQLite +databases.

+

wp:db:export

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\DbExport"
+
+

You can use WP CLI to interact with your WordPress installation, but WP CLI does not support SQLite databases in +the context of the wp db export command. +This command fills that gap by providing a database dump file export command that will support MySQL and SQLite +databases.

+

chromedriver:update

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\ChromedriverUpdate"
+
+

If you're using Chromedriver as a binary installed in the Composer vendor directory (vendor/bin by default), you can +use this command to update it. +This command will download the latest version of Chromedriver compatible with the Chrome version installed on your +machine in the Composer vendor directory.

+
+

Note: if the download fails, it might be a certificate issue.

+
+

generate:wpunit

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPUnit"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPTestCase class. +The class incorporates the WordPress test case from the wordpress-develop repository and adds some utility +methods to make testing easier in the context of Codeception.

+

The lucatume\WPBrowser\TestCase\WPTestCase class is the one that should be used when writing tests for WordPress +code when using the WPLoader module.

+

Together with the WPLoader module, the WPTestCase class provides a number of functionalities to clean up the +database +after each test method and to reset the global state of WordPress.

+

Every test method runs in a transaction

+

Database queries running in the context of test methods of a test case extending the WPTestCase class will run in a +transaction that is rolled back after the test method is run. This means that any database change happening in the +context of a test method will not appear in the database while the test is running and after the test is run.

+

generate:wpajax

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPAjax"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPAjaxTestCase class. This class is a version of the WPTestCase designed to test AJAX requests.

+

generate:wpcanonical

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPCanonical"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPCanonicalTestCase class. This class is a version of the WPTestCase designed to test canonical redirects.

+

generate:wprestapi

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPRestApi"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPRestApiTestCase class. This class is a version of the WPTestCase designed to test the handling of REST API requests.

+

generate:wprestcontroller

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPRestController"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPRestControllerTestCase class. This class is a version of the WPTestCase designed to unit-test REST API controllers.

+

generate:wprestposttypecontroller

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPRestPostTypeController"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPRestPostTypeControllerTestCase class. This class is a version of the WPTestCase designed to unit-test REST API controllers for post types.

+

generate:wpxml

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPXML"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPXMLTestCase class. This class is a version of the WPTestCase designed to test the production of XML data.

+

generate:wpxmlrpc

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\GenerateWPXMLRPC"
+
+

Generate a test case extending the lucatume\WPBrowser\TestCase\WPXMLRPCTestCase class. This class is a version of the WPTestCase designed to test the XML-RPC API.

+

monkey:cache:path

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\MonkeyCachePath"
+
+

Get the path to the monkey-patching cache directory.

+

Use the --porcelain or -p option to get the path without any additional output.

+

monkey:cache:clear

+

Enable the command with:

+
extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\MonkeyCacheClear"
+
+

Clear the monkey-patching cache.

+

Use the --porcelain or -p option to suppress any confirmation output.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/custom-configuration/index.html b/custom-configuration/index.html new file mode 100644 index 000000000..414878981 --- /dev/null +++ b/custom-configuration/index.html @@ -0,0 +1,3059 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Custom configuration - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + + + +

Custom configuration

+ +

Custom testing configuration

+

Any non default configuration is considered a custom configuration.
+If your project requires a tailored set up, this is the configuration for you.

+

Using a custom configuration to run tests

+

If you decide to skip the default configuration, or are working +on a project that cannot use the default configuration +you will be able to set up wp-browser to suit your needs using a custom configuration.

+

Choose "no", to not use the default configuration, when running the vendor/bin/codecept init wpbrowser command.

+

The command will set up the file structure to be able to run integration and end-to-end tests and will +leverage Codeception dynamic configuration using parameters to control the testing stack using the tests/.env +file.

+

Walkthrough of the tests/.env file

+
    +
  • WORDPRESS_ROOT_DIR - the path to the root WordPress installation directory. This is the directory that contains + WordPress files, like wp-load.php. This path can be absolute or relative to the root project directory; + e.g. vendor/wordpress (relative) or /var/www/wordpress (absolute) will work.
  • +
  • WORDPRESS_URL - the URL of the WordPress installation. This is the URL that will be used by the browser to access + the WordPress + installation in the context of end-to-end tests; e.g. http://localhost:8080 or https://wordpress.local.
  • +
  • WORDPRESS_DOMAIN - the domain of the WordPress installation; this value should follow the WORDPRESS_URL value. + E.g. if WORDPRESS_URL is http://localhost:8080 the WORDPRESS_DOMAIN value should be localhost:8080; + if WORDPRESS_URL is https://wordpress.local the WORDPRESS_DOMAIN value should be wordpress.local.
  • +
  • WORDPRESS_DB_URL - the user, password, host, and name of the database used by the tests. If the database is a MySQL + database, the value should be in the form mysql://user:password@host:port/database_name. + If the database is a SQLite database, the value should be in the form sqlite://path/to/database/file.
  • +
  • WORDPRESS_TABLE_PREFIX - the database table prefix used by the WordPress installation, the one served + at WORDPRESS_URL. + This value is usually wp_ but can be different if the WordPress installation has been configured to use a different + prefix.
  • +
  • TEST_TABLE_PREFIX - the database table prefix used by the WPLoader module to + install WordPress and run the tests. This value is usually test_ and should be different from + the WORDPRESS_TABLE_PREFIX value.
  • +
  • WORDPRESS_ADMIN_USER - the username of the WordPress administrator user. E.g. admin.
  • +
  • WORDPRESS_ADMIN_PASSWORD - the password of the WordPress administrator user. E.g. secret!password.
  • +
  • CHROMEDRIVER_HOST - the host of the Chromedriver server. This value is usually localhost if you're running + Chromedriver on the same machine as the tests. If you're running your tests using a container stack, it will be the + name of the container running Chromedriver, e.g. chromedriver.
  • +
  • CHROMEDRIVER_PORT - the port of the Chromedriver server. This value is usually 9515 if you're running Chromedriver + on the same machine as the tests. If you're running your tests using a container stack, it will be the port exposed by + the container running Chromedriver, e.g. 4444. Note the default configuration will set + this value to a random port during set up to avoid conflicts with other services running on the same machine.
  • +
+

Handling custom file structures

+

If your site uses a customized file structure to manage WordPress, you will need to further +configure the WPLoader module to correctly look for the site content. +Read more about setting up WPLoader to correctly load plugins and themes from custom locations here.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/default-configuration/index.html b/default-configuration/index.html new file mode 100644 index 000000000..40219dfbb --- /dev/null +++ b/default-configuration/index.html @@ -0,0 +1,3165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default configuration - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + + + +

Default configuration

+ +

Default testing configuration

+

The recommended configuration for most projects. +It allows you to get into WordPress integration and end-to-end testing quickly and easily.

+

Requirements

+

The default configuration will set up Codeception and wp-browser to use SQLite as the database engine, PHP built-in +server to serve the test site on localhost and your local version of Chrome, driven by Chromedriver, to run end-to-end +tests.

+

As such, the default configuration has the following requirements:

+
    +
  • the sqlite3 PHP extension; you can check if if's installed by running php -m | grep sqlite3 in your terminal
  • +
  • the pdo_sqlite PHP extension; you can check if if's installed by running php -m | grep pdo_sqlite in your terminal
  • +
  • PHP built-in server can work with only one thread, but it will be faster using multiple threads; multiple threads are + not supported on Windows, but they are supported on WSL.
  • +
  • the Chrome browser installed on your machine
  • +
+

Overview - plugin and theme project

+

If you're configuring wp-browser for a plugin or theme project, the default configuration will install WordPress in +the tests/_wordpress directory and configure the installation to run using SQLite as a database engine. +The SQLite Database Integration plugin) will be placed in the installation must-use plugins directory.

+

If your plugin or theme project requires additional plugins or theme to work, you can place them in +the tests/_worpdress/wp-content/plugins and tests/_wordpress/wp-content/themes directories respectively.

+

When adding, or removing, plugin and themes, remember to +update the WPLoader module configuration to load the correct plugins and themes in +your integration tests.

+

On the same note, update the database dump used by the WPDb module to reflect the +changes in the dump loaded in the end-to-end tests. +The easiest way to update the database fixture is to load the current database dump +using the wp:db:import command, manually setting up the site interacting with it and then +exporting the database dump using the wp:db:export command.

+

You can find out about the URL of the site served by the PHP built-in web server by +running the dev:info command.

+

Overview - site project

+

If you're configuring wp-browser for a site project, the default configuration will use a combination of PHP built-in +web server and the SQLite Database Integration plugin to run the tests and serve your site.

+

The router file used by the PHP built-in web server will force the site, when served on localhost, to use SQLite as +database engine leaving your existing local MySQL database untouched.

+

Your existing WordPress installation will be picked up as it is, with all the plugins and themes found in the contents +directory.

+

Existing plugins and themes are not added to WPLoader module configuration by +wp-browser, you have to do that manually.

+

Similarly, the database dump used by the WPDb module is, by default, an empty WordPress +installation where no plugins and themes are active. +You have to update the database dump used by the module to reflect the state of your site. +You can do that by loading the current database dump using the wp:db:import command, +manually setting up the site interacting with it and then +exporting the database dump using the wp:db:export command.

+

You can find out about the URL of the site served by the PHP built-in web server by +running the dev:info command.

+

When not to use the default configuration

+

The default configuration is the recommended one for most projects, but some projects might require you to use a custom +configuration to make the most out of wp-browser.

+

Database drop-in

+

The default configuration will use the SQLite Database Integration plugin to use SQLite as the database engine. +This requires placing a db.php drop-in file in the WordPress content directory.

+

If your project already requires a db.php drop-in file, you will have to use a custom configuration.

+

Multisite with sub-domains

+

While Chrome will handle sub-domains correctly, even on localhost, WordPress will not. +If you're testing a multisite installation with sub-domains, you will have to use a custom configuration.

+

Custom site structure

+

If your site uses a customized file structure to manage WordPress, you will need to configure wp-browser using a custom +configuration. +This is usually true for some site projects, and will most likely not be an issue for plugin and theme projects.

+

Using a custom configuration is not that difficult +though: read more about using a custom configuration here.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/extensions/BuiltInServerController/index.html b/extensions/BuiltInServerController/index.html new file mode 100644 index 000000000..7908cd615 --- /dev/null +++ b/extensions/BuiltInServerController/index.html @@ -0,0 +1,3027 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PHP Built-in Server Controller - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

PHP Built-in Server Controller

+ +

This extension will start and stop the PHP built-in web server before and after the tests run.

+

Configuration

+

The extension can be configured with the following parameters:

+
    +
  • required
      +
    • docroot - the document root to use for the PHP Built-in server; it can be either an absolute path or a path + relative to the Codeception root directory. Note the lowercase r in the parameter name.
    • +
    +
  • +
  • optional
      +
    • suites - an array of Codeception suites to run the server for; if not set the server will be started for all the + suites.
    • +
    • port - the port to use for the PHP Built-in server, if not set the server will use port 2389.
    • +
    • workers - the number of workers to use for the PHP Built-in server, if not set the server will use 5 workers. + This is the equivalent of the PHP_CLI_SERVER_WORKERS environment variable.
    • +
    +
  • +
+
+

Note: if you run PHP built-in server on Windows, the workers parameter will be ignored and the server will always +run with a single worker. This limit is not present in WSL.

+
+

Configuration Examples

+

Example configuration starting the server for all suites:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\BuiltInServerController"
+  config:
+    "lucatume\\WPBrowser\\Extension\\BuiltInServerController":
+      docroot: /var/www/html
+      workers: 5
+
+

The extension can access environment variables defined in the tests configuration file:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\BuiltInServerController"
+  config:
+    "lucatume\\WPBrowser\\Extension\\BuiltInServerController":
+      suites:
+        - EndToEnd
+        - WebApp
+      docroot: '%WORDPRESS_ROOT_DIR%'
+      port: '%BUILT_IN_SERVER_PORT%'
+      workers: '%BUILT_IN_SERVER_WORKERS%'
+
+

This is a service extension

+

This is a service extension that will be started and stopped by the dev:start +and dev:stop commands.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/extensions/ChromeDriverController/index.html b/extensions/ChromeDriverController/index.html new file mode 100644 index 000000000..49f4e75ad --- /dev/null +++ b/extensions/ChromeDriverController/index.html @@ -0,0 +1,3019 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ChromeDriver Controller - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

ChromeDriver Controller

+ +

This extension will start and stop the ChromeDriver before and after the tests are run.

+

Configuration

+

The extension can be configured with the following parameters:

+
    +
  • optional
      +
    • suites - an array of Codeception suites to run the server for; if not set the server will be started for all the + suites.
    • +
    • port - the port to use for the ChromeDriver, if not set the server will use port 9515.
    • +
    • binary - the path to the ChromeDriver binary, if not set the server will use the chromedriver binary in the + Composer bin directory.
    • +
    +
  • +
+

Configuration Examples

+

Example configuration starting the server for all suites:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\ChromeDriverController"
+  config:
+    "lucatume\\WPBrowser\\Extension\\ChromeDriverController":
+      port: 4444
+      binary: /usr/local/bin/chromedriver
+
+

The extension can access environment variables defined in the tests configuration file:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\ChromeDriverController"
+  config:
+    suites:
+      - EndToEnd
+      - WebApp
+    "lucatume\\WPBrowser\\Extension\\ChromeDriverController":
+      port: '%CHROMEDRIVER_PORT%'
+      binary: '%CHROMEDRIVER_BINARY%'
+
+

You can use the chromedriver:update command to download the latest version of +ChromeDriver compatible with your Chrome browser version and place it in the Composer bin directory.

+

This is a service extension

+

This is a service extension that will be started and stopped by the dev:start +and dev:stop commands.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/extensions/DockerComposeController/index.html b/extensions/DockerComposeController/index.html new file mode 100644 index 000000000..141678979 --- /dev/null +++ b/extensions/DockerComposeController/index.html @@ -0,0 +1,3015 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Docker Compose Controller - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

Docker Compose Controller

+ +

This extension will start and stop a docker compose stack before and after the tests are run.

+

Configuration

+

The extension can be configured with the following parameters:

+
    +
  • required
      +
    • compose-file - the path to the docker compose file to use; it can be either an absolute path or a path + relative to the Codeception root directory.
    • +
    +
  • +
  • optional
      +
    • env-file- the path to the environment file to use; it can be either an absolute path or a path.
    • +
    +
  • +
+

Configuration Examples

+

Example configuration starting the server for all suites:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\DockerComposeController"
+  config:
+    "lucatume\\WPBrowser\\Extension\\DockerComposeController":
+      compose-file: /var/www/html/docker-compose.yml
+      env-file: /var/www/html/.env
+
+

The extension can access environment variables defined in the tests configuration file:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\DockerComposeController"
+  config:
+    "lucatume\\WPBrowser\\Extension\\DockerComposeController":
+      compose-file: '%DOCKER_COMPOSE_FILE%'
+      env-file: '%DOCKER_COMPOSE_ENV_FILE%'
+
+

This is a service extension

+

This is a service extension that will be started and stopped by the dev:start +and wp:dev-stop commands.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/extensions/EventDispatcherBridge/index.html b/extensions/EventDispatcherBridge/index.html new file mode 100644 index 000000000..b7f57c1ce --- /dev/null +++ b/extensions/EventDispatcherBridge/index.html @@ -0,0 +1,3113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Event Dispatcher Bridge - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

Event Dispatcher Bridge

+ +

This extension connects the event dispatcher system provided by Codeception, and normally available only through the +use of custom extensions, to make it available through calls to the lucatume\WPBrowser\Events\Dispatcher class +API.

+

If not using this extension, then the only way to subscribe to events dispatched by Codeception is to use custom +extensions.

+

Configuration

+

The extension does not require configuration, it just needs to be enabled in the Codeception configuration file:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\EventDispatcherBridge"
+
+

Usage

+

The extension will automatically hook into the event dispatcher system provided by Codeception, normally available only +through the use of custom extensions, and inject user-defined event listeners in it.

+

Once the extension is enabled, you can use the lucatume\WPBrowser\Events\Dispatcher class to subscribe to Codeception +events.
+This is typically be done in either the global bootstrap file, or in a suite bootstrap file.

+

You can subscribe to the following events dispatched by Codeception in either the global bootstrap file +(usually tests/_bootstrap.php), or in a suite bootstrap file (usually tests/<suite>/_bootstrap.php):

+
    +
  • Codeception\Events::SUITE_BEFORE
  • +
  • Codeception\Events::SUITE_AFTER
  • +
  • CodeceptionventsEvents::TEST_START
  • +
  • CodeceptionventsEvents::TEST_BEFORE
  • +
  • CodeceptionventsEvents::STEP_BEFORE
  • +
  • CodeceptionventsEvents::STEP_AFTER
  • +
  • CodeceptionventsEvents::TEST_FAIL
  • +
  • CodeceptionventsEvents::TEST_ERROR
  • +
  • CodeceptionventsEvents::TEST_PARSED
  • +
  • CodeceptionventsEvents::TEST_INCOMPLETE
  • +
  • CodeceptionventsEvents::TEST_SKIPPED
  • +
  • CodeceptionventsEvents::TEST_WARNING
  • +
  • CodeceptionventsEvents::TEST_USELESS
  • +
  • CodeceptionventsEvents::TEST_SUCCESS
  • +
  • CodeceptionventsEvents::TEST_AFTER
  • +
  • CodeceptionventsEvents::TEST_END
  • +
  • CodeceptionventsEvents::TEST_FAIL_PRINT
  • +
  • CodeceptionventsEvents::RESULT_PRINT_AFTER
  • +
+

Due to order-of-operations, the earliest Codeception dispatched Event you can subscribe to is the SUITE_BEFORE one.
+To subscribe to the following earlier events, you must implement an extension following the custom extension +approach:

+
    +
  • Codeception\Events::MODULE_INIT
  • +
  • Codeception\Events::SUITE_INIT
  • +
+

The Dispatcher API documentation provides more details about the events dispatched by Codeception and wp-browser +and examples on how to subscribe to them.

+

Usage Examples

+

In the global bootstrap file (usually tests/_bootstrap.php), or the suite bootstrap file (usually +tests/<suite>/_bootstrap.php), subscribe to the Codeception events by providing a callback function that will accept +different parameters depending on the event being dispatched:

+
<?php
+
+use Codeception\Events;
+use Codeception\Event\SuiteEvent
+use Codeception\Event\TestEvent;
+use Codeception\Event\StepEvent;
+use Codeception\Event\PrintResultEvent;
+use lucatume\WPBrowser\Events\Dispatcher;
+
+Dispatcher::addListener(Events::SUITE_BEFORE, function (SuiteEvent $suiteEvent) {
+    codecept_debug('Running on SUITE BEFORE');
+});
+
+Dispatcher::addListener(Events::SUITE_AFTER, function (SuiteEvent $suiteEvent) {
+    codecept_debug('Running on SUITE AFTER');
+});
+
+Dispatcher::addListener(Events::TEST_START, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST START');
+});
+
+Dispatcher::addListener(Events::TEST_BEFORE, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST BEFORE');
+});
+
+Dispatcher::addListener(Events::STEP_BEFORE, function (StepEvent $stepEvent) {
+    codecept_debug('Running on STEP BEFORE');
+});
+
+Dispatcher::addListener(Events::STEP_AFTER, function (StepEvent $stepEvent) {
+    codecept_debug('Running on STEP AFTER');
+});
+
+Dispatcher::addListener(Events::TEST_FAIL, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST FAIL');
+});
+
+Dispatcher::addListener(Events::TEST_ERROR, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST ERROR');
+});
+
+Dispatcher::addListener(Events::TEST_PARSED, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST PARSED');
+});
+
+Dispatcher::addListener(Events::TEST_INCOMPLETE, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST INCOMPLETE');
+});
+
+Dispatcher::addListener(Events::TEST_SKIPPED, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST SKIPPED');
+});
+
+Dispatcher::addListener(Events::TEST_WARNING, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST WARNING');
+});
+
+Dispatcher::addListener(Events::TEST_USELESS, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST USELESS');
+});
+
+Dispatcher::addListener(Events::TEST_SUCCESS, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST SUCCESS');
+});
+
+Dispatcher::addListener(Events::TEST_AFTER, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST AFTER');
+});
+
+Dispatcher::addListener(Events::TEST_END, function (TestEvent $testEvent) {
+    codecept_debug('Running on TEST END');
+});
+
+Dispatcher::addListener(Events::TEST_FAIL_PRINT, function (PrintResultEvent $printResultEvent) {
+    codecept_debug('Running on TEST FAIL PRINT');
+});
+
+Dispatcher::addListener(Events::RESULT_PRINT_AFTER, function (PrintResultEvent $printResultEvent) {
+    codecept_debug('Running on RESULT PRINT AFTER');
+});
+
+

Read more about the Dispatcher API here.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/extensions/IsolationSupport/index.html b/extensions/IsolationSupport/index.html new file mode 100644 index 000000000..2e98c1c98 --- /dev/null +++ b/extensions/IsolationSupport/index.html @@ -0,0 +1,2993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Isolation Support - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

Isolation Support

+ +

This extension provides support for the PHPUnit annotations @runInSeparateProcess and @runTestsInSeparateProcesses, +and the PHPUnit attributes (PHPUnit 10+) #[RunInSeparateProcess] and #[RunTestsInSeparateProcesses].
+You can read more about these annotations and attributes in the PHPUnit documentation about test isolation.

+

Codeception does not natively support these annotations and attributes, this extension provides support for them.

+

Configuration

+

You can enable the extension in the Codeception configuration file:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\IsolationSupport"
+
+

In your tests, you can use the annotations or attributes as you would in a PHPUnit test:

+
<?php
+
+use lucatume\WPBrowser\TestCase\WPTestCase;
+
+class IsolationExampleTest extends WPTestCase {
+    /**
+     * @runInSeparateProcess
+     */
+    public function test_in_admin_context() {
+        define('WP_ADMIN', true);
+
+        $this->assertTrue(is_admin());
+    }
+
+    #[RunTestsInSeparateProcesses]
+    public function test_in_admin_context_with_attribute() {
+        define('WP_ADMIN', true);
+
+        $this->assertTrue(is_admin());
+    }
+
+    public function test_constant_is_not_set() {
+        $this->assertFalse(defined('WP_ADMIN'));
+    }
+}
+
+#[RunTestsInSeparateProcesses]
+class RunAllTestsInSeparateProcesses extends WPTestCase {
+    public function test_one() {
+        definen('TEST_CONST', 'one');
+
+        $this->assertEquals('one', TEST_CONST);
+    }
+
+    public function test_two() {
+        definen('TEST_CONST', 'two');
+
+        $this->assertEquals('two', TEST_CONST);
+    }
+}
+
+
+

Previous versions of the test isolation support required the @backupGlobals disabled annotation to be used when +running tests in isolation. This is no longer required.

+
+

Isolation support is based around monkey-patching the file at runtime. Look into the monkey:cache:clear +and monkey:cache:path commands to manage the monkey-patching cache.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/extensions/Symlinker/index.html b/extensions/Symlinker/index.html new file mode 100644 index 000000000..a7fd90e7f --- /dev/null +++ b/extensions/Symlinker/index.html @@ -0,0 +1,2934 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Symlinker - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

Symlinker

+ +

This extension will symlink the plugins and themes specified in the plugins and themes configuration parameters to +the WordPress installation plugins and themes directories, respectively.

+

The plugins and themes will be symlinked before each suite, and removed after each suite.

+

Configuration

+

The extension can be configured with the following parameters:

+
    +
  • required
      +
    • wpRootFolder - the relative (to the current working directory) or absolute path to the WordPress installation + root folder, the directory that contains the wp-load.php file.
    • +
    +
  • +
  • optional
      +
    • cleanupAfterSuite - default false, a boolean value to indicate if the symlinks created by the extension + sshould be removed after the suite ran.
    • +
    • plugins- a list of plugin directories to symlink to the WordPress installation plugins directory, if not set + the plugin symlinking will be skipped.
    • +
    • themes- a list of theme directories to symlink to the WordPress installation themes directory, if not set + the theme symlinking will be skipped.
    • +
    +
  • +
+

Configuration Examples

+

Example configuration symbolically linking the plugins and themes to the WordPress installation plugins and themes +directories:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\Symlinker"
+  config:
+    "lucatume\\WPBrowser\\Extension\\Symlinker":
+      wpRootFolder: /var/www/html
+      plugins:
+        - '.' # Relative path, the current working directory.
+        - /home/plugins/plugin-1 # Absolute path to a plugin directory.
+        - vendor/acme/plugin-2 # Relative path to a plugin directory.
+      themes:
+        - /home/theme-1 # Absolute path to a theme directory.
+        - vendor/acme/theme-2 # Relative path to a theme directory.
+
+

The extension can access environment variables defined in the tests configuration file:

+
extensions:
+  enabled:
+    - "lucatume\\WPBrowser\\Extension\\Symlinker"
+  config:
+    "lucatume\\WPBrowser\\Extension\\Symlinker":
+      wpRootFolder: '%WP_ROOT_FOLDER%'
+      plugins:
+        - '%PLUGIN_STORAGE%/plugin-1'
+        - '%PLUGIN_STORAGE%/plugin-2'
+      themes:
+        - '%THEME_STORAGE%/theme-1'
+        - '%THEME_STORAGE%/theme-2'
+
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/extensions/index.html b/extensions/index.html new file mode 100644 index 000000000..09300530d --- /dev/null +++ b/extensions/index.html @@ -0,0 +1,2857 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Extensions - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + +
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..74eb40f2f --- /dev/null +++ b/index.html @@ -0,0 +1,3148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Getting started - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+ +
+ + + +
+ +
+ + + + + + + + +

Getting started

+ +
+

This is the documentation for version 4 of the project, the current version. +Documentation for the previous version of the project, version 3, can be found here.

+
+

The wp-browser library provides a set of Codeception modules and middleware to enable the testing of WordPress sites, plugins and themes.

+

Requirements

+

Depending on the nature of your project, there are different requirements it will need to satisfy before getting started.

+

Site

+
    +
  • Ensure you're running the vendor/bin/codecept init wpbrowser command from the root directory of your WordPress site.
  • +
  • Ensure the directory contains the WordPress installation files. In a standard scenario you should have extracted WordPress files in this directory.
  • +
  • Ensure your installation is configured: it should contain a wp-config.php file.
  • +
+

Plugin

+
    +
  • Ensure you're running the vendor/bin/codecept init wpbrowser command from the root directory of your plugin; this should be the directory that contains the PHP file defining the plugin header.
  • +
+

Theme

+
    +
  • Ensure you're running the vendor/bin/codecept init wpbrowser command from the root directory of your theme; this should be the directory that contains the style.css file defining the theme header.
  • +
+

If you decide to use the quick installation, then your PHP version should have the sqlite3 extensions installed and activated. You can check this using the php -m command and verifying the sqlite3 extension is among the active extensions.

+

Installation

+

Add wp-browser to your project as a development dependency using Composer

+
cd my-wordrpess-project
+composer require --dev lucatume/wp-browser
+
+

Initialize wp-browser to quickly configured to suite your project and setup:

+
vendor/bin/codecept init wpbrowser
+
+

The command will set up your project to run integration and end-to-end tests using:

+
    +
  • SQLite as the database engine, leveraging the SQLite Database Integration plugin
  • +
  • PHP built-in web server to serve the WordPress site on localhost (e.g. http://localhost:8080)
  • +
  • Chromedriver to drive the local version of Chrome installed on your machine
  • +
+

If you're working on a plugin or theme project, the default configuration will add some extra steps:

+
    +
  • install the latest version of WordPress in the tests/_wordpress directory
  • +
  • create a tests/_plugins directory: any file or directory in this directory will be symlinked into the WordPress + installation in tests/_wordpress/wp-content/plugins
  • +
  • create a tests/_themes directory: any file or directory in this directory will be symlinked into the WordPress + installation in tests/_wordpress/wp-content/themes
  • +
+

For most projects this configuration will be enough to get started with testing.

+

You can run your tests immediately using the vendor/bin/codecept run command.

+

Read more about the commands provided by the library here.

+

Using a custom configuration

+

If you decide to skip the default configuration, you will be able to set up wp-browser to suit your needs and local +setup by editing the tests/.env file. +The inline documentation in the file will guide you through the configuration process.

+

Read more about using a custom configuration here.

+

Getting support for wp-browser configuration and usage

+

The best place to get support for wp-browser is the project documentation.
+Since this project builds on top of PHPUnit and Codeception, you can also refer to their documentation.

+

If you can't find the answer to your question here you can ask on +the "Issues" section of the wp-browser repository taking care to provide as much information as possible.

+

Finally, you can contact me directly to set up a call to discuss your +project needs and how wp-browser can help you.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/migration/index.html b/migration/index.html new file mode 100644 index 000000000..dcfbd36cf --- /dev/null +++ b/migration/index.html @@ -0,0 +1,3188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Migrating to newer versions - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + + + +

Migrating to newer versions

+ +

Depending on your project PHP compatibility, you have three options to choose from:

+ +

Version 3.5 and 4.0

+

Version 3.5 and 4.0 are the latest versions of wp-browser.
+Version 3.5 is a transpile of version 4 to be compatible with PHP 7.1 to 7.4 that contains, for all intents and +purposes, the same facilities and systems contained in version 4 of wp-browser adapter to work on lower PHP versions +and version 4 of Codeception.

+

Future development of wp-browser will happen on version 4 and will be transpiled to version 3.5 for +back-compatibility purposes.

+

Migrate from version 3 to 3.5

+
    +
  1. Update the required version of wp-browser in your composer.json file to 3.5: +
    {
    +  "require-dev": {
    +    "lucatume/wp-browser": "^3.5"
    +  }
    +}
    +
  2. +
  3. See the changes common to version 3.5 and 4.0
  4. +
+

Migrate from version 3 to 4

+
    +
  1. Update the required version of wp-browser in your composer.json file to 4.0: +
    {
    +  "require-dev": {
    +    "lucatume/wp-browser": "^4.0"
    +  }
    +}
    +
  2. +
  3. See the changes common to version 3.5 and 4.0
  4. +
+

Changes common to version 3.5 and 4.0

+
    +
  1. Update your main Codeception configuration file (e.g. codeception.yml) to enable the new commands:
  2. +
+

extensions:
+  commands:
+    - "lucatume\\WPBrowser\\Command\\RunOriginal"
+    - "lucatume\\WPBrowser\\Command\\RunAll"
+    - "lucatume\\WPBrowser\\Command\\DbExport"
+    - "lucatume\\WPBrowser\\Command\\DbImport"
+    - "lucatume\\WPBrowser\\Command\\MonkeyCachePath"
+    - "lucatume\\WPBrowser\\Command\\MonkeyCacheClear"
+
+2. Along with the new commands, update the existing commands to use the lucatume\WPBrowser\Command\ namespace:

+

extensions:
+  commands:
+-    - "Codeception\\Command\\GenerateWPUnit"
+-    - "Codeception\\Command\\GenerateWPRestApi"
+-    - "Codeception\\Command\\GenerateWPRestController"
+-    - "Codeception\\Command\\GenerateWPRestPostTypeController"
+-    - "Codeception\\Command\\GenerateWPAjax"
+-    - "Codeception\\Command\\GenerateWPCanonical"
+-    - "Codeception\\Command\\GenerateWPXMLRPC"
++    - "lucatume\\WPBrowser\\Command\\GenerateWPUnit"
++    - "lucatume\\WPBrowser\\Command\\GenerateWPRestApi"
++    - "lucatume\\WPBrowser\\Command\\GenerateWPRestController"
++    - "lucatume\\WPBrowser\\Command\\GenerateWPRestPostTypeController"
++    - "lucatume\\WPBrowser\\Command\\GenerateWPAjax"
++    - "lucatume\\WPBrowser\\Command\\GenerateWPCanonical"
++    - "lucatume\\WPBrowser\\Command\\GenerateWPXMLRPC"
+
+3. If your test code is loading deprecated functions, arguments, classes, files, or hooks, you need to update your test + code to let the test case know using the setExpectedDeprecated method: +
<?php
+
+use lucatume\WPBrowser\TestCase\WPTestCase;
+
+class MyTestUsingDeprecatedCode extends WPTestCase {
+    public function test_deprecatd_function() {
+        // add_filter( 'deprecated_function_trigger_error', '__return_false' );
+        $this->setExpectedDeprecated( 'my_deprecated_function' );
+        my_deprecated_function();
+    }
+
+    public function test_deprecated_class(){
+        // add_filter( 'deprecated_class_trigger_error', '__return_false' );
+        $this->setExpectedDeprecated( 'MyDeprecatedClass' );
+        new MyDeprecatedClass();
+    }
+
+    public function test_deprecated_file(){
+        // add_filter( 'deprecated_file_trigger_error', '__return_false' );
+        $this->setExpectedDeprecated( '/path/to/my_deprecated_file.php' );
+        require_once 'my_deprecated_file.php';
+    }
+
+    public function test_deprecated_hook(){
+        // add_filter( 'deprecated_hook_trigger_error', '__return_false' );
+        $this->setExpectedDeprecated( 'my_deprecated_hook' );
+        do_action( 'my_deprecated_hook' );
+    }
+}
+
+ Previously, your code could just filter + the deprecated_function_trigger_error, deprecated_argument_trigger_error, deprecated_class_trigger_error, deprecated_file_trigger_error, and deprecated_hook_trigger_error, hooks to return false to tolerate the deprecation notices in tests.
+4. If your test code is directly modifying properties like $expected_deprecated or $expected_doing_it_wrong directly, you need to update your test code to use the setExpectedDeprecated and setExpectedIncorrectUsage methods: +
<?php
+
+use lucatume\WPBrowser\TestCase\WPTestCase;
+class MyTestUsingDeprecatedCode extends WPTestCase {
+    public function test_deprecated_function() {
+        // $this->expected_deprecated[] = 'my_deprecated_function';
+        $this->setExpectedDeprecated( 'my_deprecated_function' );
+        my_deprecated_function();
+    }
+
+    public function test_doing_it_wrong(){
+        // $this->expected_doing_it_wrong[] = 'my_doing_it_wrong';
+        $this->setExpectedIncorrectUsage( 'my_doing_it_wrong' );
+        my_doing_it_wrong();
+    }
+}
+
+5. If your test code is knowingly triggering doing-it-wrong notices, you need to update your test code to let the test + case know using the setExpectedIncorrectUsage method: +
<?php
+
+use lucatume\WPBrowser\TestCase\WPTestCase;
+class MyTestUsingDoingItWrongTest extends WPTestCase {
+    public function test_it_can_use_doing_it_wrong() {
+        $this->setExpectedIncorrectUsage( 'my_doing_it_wrong' );
+        my_doing_it_wrong();
+    }
+}
+
+ Previously, your code could just filter the doing_it_wrong_trigger_error hook to return false to tolerate the + doing-it-wrong notices in tests.
+6. Some assertion methods have, in more recent versions of the PHPUnit core suite, adopted stricter type checks when it comes to comparison. E.g., the assertEqualFields will now check the object to check the fields on is actually an object. Depending on how loose your use of assertions was before, you might have to update your work to make it pass the stricter checks: +
<?php
+
+use lucatume\WPBrowser\TestCase\WPTestCase;
+
+ class MyTestUsingAssertEqualFields extends WPTestCase {
+      public function test_it_can_use_assert_equal_fields() {
+         // Cast the array to an object explicitly.
+         $this->assertEqualFields( (object) [ 'a' => 1 ], [ 'a' => 1 ] );
+      }
+ }
+
+7. Other updates to the Core PHPUnit test case will report use of deprecated functions more promptly; if your code is using deprecated functions that might have escaped previous versions of wp-browser, you will need to update them.
+8. If you're using the @runInSeparateProcess annotation for tests in your suite, you will need to enable the IsolationSupport extension in your suite configuration file:

+
actor: MySuiteTester
+bootstrap: _bootstrap.php
+extensions:
+enabled:
+   - "lucatume\\WPBrowser\\Extension\\IsolationSupport"
+modules: # The rest of the module configuration ...
+
+

Alternatively, you can enable the extension in the Codeception main configuration file (e.g. codeception.yml).

+

Read more about the extension in the Isolation Support extension documentation.
+9. Global space cleanup between test is more thorough in more recent versions of the Core PHPUnit test suite. Due to this you might see failures in tests that were passing in previous versions due to a "leaking" global state. Examples of this might be nonces being set by previous tests and not being reset. Update your tests to explicitly set all the global stat variables you require for the test to run.

+

Staying on version 3, lower than 3.5

+

Update your composer.json file to lock the required version of wp-browser to a version less than 3.5:

+
{
+  "require-dev": {
+    "lucatume/wp-browser": "<3.5"
+  }
+}
+
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/AirplaneMode/index.html b/modules/AirplaneMode/index.html new file mode 100644 index 000000000..900c0a769 --- /dev/null +++ b/modules/AirplaneMode/index.html @@ -0,0 +1,2981 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Airplane Mode - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

Airplane Mode

+ +

AirplaneMode module

+

This module allows you to easily put the website under test in "airplane mode", preventing it from making any network requests.

+

The module uses the norcross/airplane-mode plugin to add or remove it from the website must-use plugins directory when activated.

+

This module should be used together with the WPWebDriver or WPBrowser modules.

+

Configuration

+
    +
  • muPluginsDir - required; the path to the WordPress must-use plugins directory.
  • +
  • symlink - whether to symlink the plugin or copy it. By default, the plugin is copied in the must-use plugins directory and symlink is set to false. If you're not using containers, that will ignore symlinked plugins, you can set symlink to true to symlink the plugin in the must-use plugins directory. Symbolic linking is faster and uses less disk space than copying the plugin.
  • +
+

Example configuration to symlink the plugin in the muPluginsDir directory before the tests:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\AirplaneMode:
+      muPluginsDir: 'var/wordpress/wp-content/mu-plugins'
+      symlink: true
+
+

Example configuration to copy the plugin in the muPluginsDir directory before the tests:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\AirplaneMode:
+      muPluginsDir: 'var/wordpress/wp-content/mu-plugins'
+      symlink: false
+
+

The module will either symlink or copy the plugin in the muPluginsDir directory, depending on the symlink configuration parameter before the test suite runs, and will remove it after the test suite has run.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/WPBrowser/index.html b/modules/WPBrowser/index.html new file mode 100644 index 000000000..13e354b8d --- /dev/null +++ b/modules/WPBrowser/index.html @@ -0,0 +1,5659 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPBrowser - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

WPBrowser

+ +

WPBrowser module

+

Browse and test the site HTML with a fast browser without Javascript support.

+

This module trades the WPWebDriver module Javascript support for speed and stability. It is a good +choice for testing sites that don't use Javascript or to make assertions that do not require Javascript support like:

+
    +
  • testing HTTP return codes
  • +
  • testing HTML structure
  • +
  • testing JSON and XML responses from APIs
  • +
+

This module is used together with the WPDb module and the WPFilesystem module to +control the site state, the database, and the site file structure.

+

This module is an extension of the Codeception PHPBrowser module, you can reference to the Codeception module +documentation for more information on the module configuration and usage.

+

This module should be with Cest and Cept test cases.

+

Configuration

+
    +
  • url - required; the start URL of your WordPress project.
  • +
  • adminUsername - required; the site administrator username to use in actions like loginAsAdmin.
  • +
  • adminPassword - required; the site administrator password to use in actions like loginAsAdmin.
  • +
  • adminPath - the path to the WordPress admin directory; defaults to /wp-admin.
  • +
+

More Guzzle request options are available like:

+

headers - default headers are set before each test.
+cookies - default cookies are set before each test.
+auth - default authentication to be set before each test.

+

... and more.

+

The following is an example of the module configuration to run tests on thehttp://localhost:8080 site:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPBrowser:
+      url: 'http://localhost:8080'
+      adminUsername: 'admin'
+      adminPassword: 'password'
+      adminPath: '/wp-admin'
+      headers:
+        X_WPBROWSER_REQUEST: 1
+        X_TEST_REQUEST: 1
+        X_APM_REQUEST: 1
+
+

The following configuration uses dynamic configuration parameters to set the module configuration:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPBrowser:
+      url: '%WORDPRESS_URL%'
+      adminUsername: '%WORDPRESS_ADMIN_USER%'
+      adminPassword: '%WORDPRESS_ADMIN_PASSWORD%'
+      adminPath: '/wp-admin'
+      headers:
+        X_WPBROWSER_REQUEST: 1
+        X_TEST_REQUEST: 1
+        X_APM_REQUEST: 1
+
+

Methods

+

The module provides the following methods:

+ + +

activatePlugin

+

Signature: activatePlugin(array|string $pluginSlug) : void

+

In the plugin administration screen activates a plugin clicking the "Activate" link.

+

The method will not handle authentication to the admin area.

+
<?php
+// Activate a plugin.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->activatePlugin('hello-dolly');
+// Activate a list of plugins.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->activatePlugin(['hello-dolly','another-plugin']);
+
+

activateTheme

+

Signature: activateTheme(string $slug) : void

+

Activates a theme.

+

The method will not handle authentication and navigation to the themes administration page.

+

amEditingPostWithId

+

Signature: amEditingPostWithId(int $id) : void

+

Go to the admin page to edit the post with the specified ID.

+

The method will not handle authentication the admin area.

+
<?php
+$I->loginAsAdmin();
+$postId = $I->havePostInDatabase();
+$I->amEditingPostWithId($postId);
+$I->fillField('post_title', 'Post title');
+
+

amEditingUserWithId

+

Signature: amEditingUserWithId(int $id) : void

+

Go to the admin page to edit the user with the specified ID.

+

The method will not handle authentication the admin area.

+
<?php
+$I->loginAsAdmin();
+$userId = $I->haveUserInDatabase('luca', 'editor');
+$I->amEditingUserWithId($userId);
+$I->fillField('email', 'new@example.net');
+
+

amHttpAuthenticated

+

Signature: amHttpAuthenticated($username, $password) : void

+

amOnAdminAjaxPage

+

Signature: amOnAdminAjaxPage([array|string|null $queryVars]) : void

+

Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.

+

The method will not handle authentication, nonces or authorization.

+
<?php
+$I->amOnAdminAjaxPage(['action' => 'my-action', 'data' => ['id' => 23], 'nonce' => $nonce]);
+
+

amOnAdminPage

+

Signature: amOnAdminPage(string $page) : void

+

Go to a page in the admininstration area of the site.

+

This method will not handle authentication to the administration area.

+
<?php
+$I->loginAs('user', 'password');
+// Go to the plugins management screen.
+$I->amOnAdminPage('/plugins.php');
+
+

amOnCronPage

+

Signature: amOnCronPage([array|string|null $queryVars]) : void

+

Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

+
<?php
+// Triggers the cron job with an optional query argument.
+$I->amOnCronPage('/?some-query-var=some-value');
+
+

amOnPage

+

Signature: amOnPage(string $page) : void

+

amOnPagesPage

+

Signature: amOnPagesPage() : void

+

Go the "Pages" administration screen.

+

The method will not handle authentication.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPagesPage();
+$I->see('Add New');
+
+

amOnPluginsPage

+

Signature: amOnPluginsPage() : void

+

Go to the plugins administration screen.

+

The method will not handle authentication.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->activatePlugin('hello-dolly');
+
+

amOnSubdomain

+

Signature: amOnSubdomain($subdomain) : void

+

amOnThemesPage

+

Signature: amOnThemesPage() : void

+

Moves to the themes administration page.

+

amOnUrl

+

Signature: amOnUrl($url) : void

+

attachFile

+

Signature: attachFile($field, string $filename) : void

+

checkOption

+

Signature: checkOption($option) : void

+

click

+

Signature: click($link, [$context]) : void

+

deactivatePlugin

+

Signature: deactivatePlugin(array|string $pluginSlug) : void

+

In the plugin administration screen deactivate a plugin clicking the "Deactivate" link.

+

The method will not handle authentication and navigation to the plugins administration page.

+
<?php
+// Deactivate one plugin.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->deactivatePlugin('hello-dolly');
+// Deactivate a list of plugins.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->deactivatePlugin(['hello-dolly', 'my-plugin']);
+
+

deleteHeader

+

Signature: deleteHeader(string $name) : void

+

Deletes the header with the passed name. Subsequent requests +will not have the deleted header in its request.

+

Example: +

<?php
+$I->haveHttpHeader('X-Requested-With', 'Codeception');
+$I->amOnPage('test-headers.php');
+// ...
+$I->deleteHeader('X-Requested-With');
+$I->amOnPage('some-other-page.php');
+

+

dontSee

+

Signature: dontSee(string $text, [$selector]) : void

+

dontSeeCheckboxIsChecked

+

Signature: dontSeeCheckboxIsChecked($checkbox) : void

+

dontSeeCookie

+

Signature: dontSeeCookie($cookie, [$params]) : void

+

dontSeeCurrentUrlEquals

+

Signature: dontSeeCurrentUrlEquals(string $uri) : void

+

dontSeeCurrentUrlMatches

+

Signature: dontSeeCurrentUrlMatches(string $uri) : void

+

dontSeeElement

+

Signature: dontSeeElement($selector, [array $attributes]) : void

+

dontSeeInCurrentUrl

+

Signature: dontSeeInCurrentUrl(string $uri) : void

+

dontSeeInField

+

Signature: dontSeeInField($field, $value) : void

+

dontSeeInFormFields

+

Signature: dontSeeInFormFields($formSelector, array $params) : void

+

dontSeeInSource

+

Signature: dontSeeInSource(string $raw) : void

+

dontSeeInTitle

+

Signature: dontSeeInTitle($title) : void

+ +

Signature: dontSeeLink(string $text, [string $url]) : void

+

dontSeeOptionIsSelected

+

Signature: dontSeeOptionIsSelected($selector, $optionText) : void

+

dontSeePluginInstalled

+

Signature: dontSeePluginInstalled(string $pluginSlug) : void

+

Assert a plugin is not installed in the plugins administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->dontSeePluginInstalled('my-plugin');
+
+

dontSeeResponseCodeIs

+

Signature: dontSeeResponseCodeIs(int $code) : void

+

Checks that response code is equal to value provided.

+
<?php
+$I->dontSeeResponseCodeIs(200);
+
+// recommended \Codeception\Util\HttpCode
+$I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
+
+

executeInGuzzle

+

Signature: executeInGuzzle(Closure $function) : void

+

Low-level API method. +If Codeception commands are not enough, use Guzzle HTTP Client methods directly

+

Example:

+
<?php
+$I->executeInGuzzle(function (\GuzzleHttp\Client $client) {
+     $client->get('/get', ['query' => ['foo' => 'bar']]);
+});
+
+

It is not recommended to use this command on a regular basis. +If Codeception lacks important Guzzle Client methods, implement them and submit patches.

+

fillField

+

Signature: fillField($field, $value) : void

+

followRedirect

+

Signature: followRedirect() : void

+

Follow pending redirect if there is one.

+
<?php
+$I->followRedirect();
+
+

grabActiveTheme

+

Signature: grabActiveTheme() : ?string

+

Returns the slug of the currently active themes.

+

The method will not handle authentication and navigation to the themes administration page.

+

grabAttributeFrom

+

Signature: grabAttributeFrom($cssOrXpath, string $attribute) : mixed

+

grabAvailableThemes

+

Signature: grabAvailableThemes([string $classes]) : array

+

Returns the list of available themes.

+

The method will not handle authentication and navigation to the themes administration page.

+

grabCookie

+

Signature: grabCookie(string $cookie, [array $params]) : mixed

+

grabCookiesWithPattern

+

Signature: grabCookiesWithPattern(string $cookiePattern) : ?array

+

Returns all the cookies whose name matches a regex pattern.

+
<?php
+$I->loginAs('customer','password');
+$I->amOnPage('/shop');
+$cartCookies = $I->grabCookiesWithPattern("#^shop_cart\\.*#");
+
+

grabFromCurrentUrl

+

Signature: grabFromCurrentUrl([?string $uri]) : mixed

+

grabMultiple

+

Signature: grabMultiple($cssOrXpath, [?string $attribute]) : array

+

grabPageSource

+

Signature: grabPageSource() : string

+

Grabs current page source code.

+

grabTextFrom

+

Signature: grabTextFrom($cssOrXPathOrRegex) : mixed

+

grabValueFrom

+

Signature: grabValueFrom($field) : mixed

+

grabWordPressTestCookie

+

Signature: grabWordPressTestCookie([?string $name]) : ?Symfony\Component\BrowserKit\Cookie

+

Returns WordPress default test cookie object if present.

+
<?php
+// Grab the default WordPress test cookie.
+$wpTestCookie = $I->grabWordPressTestCookie();
+// Grab a customized version of the test cookie.
+$myTestCookie = $I->grabWordPressTestCookie('my_test_cookie');
+
+

haveHttpHeader

+

Signature: haveHttpHeader(string $name, string $value) : void

+

Sets the HTTP header to the passed value - which is used on +subsequent HTTP requests through PhpBrowser.

+

Example: +

<?php
+$I->haveHttpHeader('X-Requested-With', 'Codeception');
+$I->amOnPage('test-headers.php');
+

+

To use special chars in Header Key use HTML Character Entities: +Example: +Header with underscore - 'Client_Id' +should be represented as - 'Client_Id' or 'Client_Id'

+
<?php
+$I->haveHttpHeader('Client&#95;Id', 'Codeception');
+
+

haveServerParameter

+

Signature: haveServerParameter(string $name, string $value) : void

+

Sets SERVER parameter valid for all next requests.

+
<?php
+$I->haveServerParameter('name', 'value');
+
+

logOut

+

Signature: logOut([string|bool $redirectTo]) : void

+

Navigate to the default WordPress logout page and click the logout link.

+
<?php
+// Log out using the `wp-login.php` form and return to the current page.
+$I->logOut(true);
+// Log out using the `wp-login.php` form and remain there.
+$I->logOut(false);
+// Log out using the `wp-login.php` form and move to another page.
+$I->logOut('/some-other-page');
+
+

loginAs

+

Signature: loginAs(string $username, string $password) : void

+

Login as the specified user.

+

The method will not follow redirection, after the login, to any page.

+
<?php
+$I->loginAs('user', 'password');
+$I->amOnAdminPage('/');
+$I->see('Dashboard');
+
+

loginAsAdmin

+

Signature: loginAsAdmin() : void

+

Login as the administrator user using the credentials specified in the module configuration.

+

The method will not follow redirection, after the login, to any page.

+
<?php
+$I->loginAsAdmin();
+$I->amOnAdminPage('/');
+$I->see('Dashboard');
+
+

makeHtmlSnapshot

+

Signature: makeHtmlSnapshot([?string $name]) : void

+

moveBack

+

Signature: moveBack([int $numberOfSteps]) : void

+

Moves back in history.

+

resetCookie

+

Signature: resetCookie($cookie, [$params]) : void

+

see

+

Signature: see(string $text, [$selector]) : void

+

seeCheckboxIsChecked

+

Signature: seeCheckboxIsChecked($checkbox) : void

+

seeCookie

+

Signature: seeCookie($cookie, [$params]) : void

+

seeCurrentUrlEquals

+

Signature: seeCurrentUrlEquals(string $uri) : void

+

seeCurrentUrlMatches

+

Signature: seeCurrentUrlMatches(string $uri) : void

+

seeElement

+

Signature: seeElement($selector, [array $attributes]) : void

+

seeErrorMessage

+

Signature: seeErrorMessage([array|string $classes]) : void

+

In an administration screen look for an error admin notice.

+

The check is class-based to decouple from internationalization. +The method will not handle authentication and navigation the administration area.

+
<?php
+$I->loginAsAdmin()
+$I->amOnAdminPage('/');
+$I->seeErrorMessage('.my-plugin');
+
+

seeInCurrentUrl

+

Signature: seeInCurrentUrl(string $uri) : void

+

seeInField

+

Signature: seeInField($field, $value) : void

+

seeInFormFields

+

Signature: seeInFormFields($formSelector, array $params) : void

+

seeInSource

+

Signature: seeInSource(string $raw) : void

+

seeInTitle

+

Signature: seeInTitle($title) : void

+ +

Signature: seeLink(string $text, [?string $url]) : void

+

seeMessage

+

Signature: seeMessage([array|string $classes]) : void

+

In an administration screen look for an admin notice.

+

The check is class-based to decouple from internationalization. +The method will not handle authentication and navigation the administration area.

+
<?php
+$I->loginAsAdmin()
+$I->amOnAdminPage('/');
+$I->seeMessage('.missing-api-token.my-plugin');
+
+

seeNumberOfElements

+

Signature: seeNumberOfElements($selector, $expected) : void

+

seeOptionIsSelected

+

Signature: seeOptionIsSelected($selector, $optionText) : void

+

seePageNotFound

+

Signature: seePageNotFound() : void

+

Asserts that current page has 404 response status code.

+

seePluginActivated

+

Signature: seePluginActivated(string $pluginSlug) : void

+

Assert a plugin is activated in the plugin administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->seePluginActivated('my-plugin');
+
+

seePluginDeactivated

+

Signature: seePluginDeactivated(string $pluginSlug) : void

+

Assert a plugin is not activated in the plugins administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->seePluginDeactivated('my-plugin');
+
+

seePluginInstalled

+

Signature: seePluginInstalled(string $pluginSlug) : void

+

Assert a plugin is installed, no matter its activation status, in the plugin administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->seePluginInstalled('my-plugin');
+
+

seeResponseCodeIs

+

Signature: seeResponseCodeIs(int $code) : void

+

Checks that response code is equal to value provided.

+
<?php
+$I->seeResponseCodeIs(200);
+
+// recommended \Codeception\Util\HttpCode
+$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
+
+

seeResponseCodeIsBetween

+

Signature: seeResponseCodeIsBetween(int $from, int $to) : void

+

Checks that response code is between a certain range. Between actually means [from <= CODE <= to]

+

seeResponseCodeIsClientError

+

Signature: seeResponseCodeIsClientError() : void

+

Checks that the response code is 4xx

+

seeResponseCodeIsRedirection

+

Signature: seeResponseCodeIsRedirection() : void

+

Checks that the response code 3xx

+

seeResponseCodeIsServerError

+

Signature: seeResponseCodeIsServerError() : void

+

Checks that the response code is 5xx

+

seeResponseCodeIsSuccessful

+

Signature: seeResponseCodeIsSuccessful() : void

+

Checks that the response code 2xx

+

seeThemeActivated

+

Signature: seeThemeActivated(string $slug) : void

+

Verifies that a theme is active.

+

The method will not handle authentication and navigation to the themes administration page.

+

seeWpDiePage

+

Signature: seeWpDiePage() : void

+

Checks that the current page is one generated by the wp_die function.

+

The method will try to identify the page based on the default WordPress die page HTML attributes.

+
<?php
+$I->loginAs('user', 'password');
+$I->amOnAdminPage('/forbidden');
+$I->seeWpDiePage();
+
+

selectOption

+

Signature: selectOption($select, $option) : void

+

sendAjaxGetRequest

+

Signature: sendAjaxGetRequest(string $uri, [array $params]) : void

+

Sends an ajax GET request with the passed parameters. +See sendAjaxPostRequest()

+

sendAjaxPostRequest

+

Signature: sendAjaxPostRequest(string $uri, [array $params]) : void

+

Sends an ajax POST request with the passed parameters. +The appropriate HTTP header is added automatically: +X-Requested-With: XMLHttpRequest +Example: +

<?php
+$I->sendAjaxPostRequest('/add-task', ['task' => 'lorem ipsum']);
+
+Some frameworks (e.g. Symfony) create field names in the form of an "array": +<input type="text" name="form[task]"> +In this case you need to pass the fields like this: +
<?php
+$I->sendAjaxPostRequest('/add-task', ['form' => [
+    'task' => 'lorem ipsum',
+    'category' => 'miscellaneous',
+]]);
+

+

sendAjaxRequest

+

Signature: sendAjaxRequest(string $method, string $uri, [array $params]) : void

+

Sends an ajax request, using the passed HTTP method. +See sendAjaxPostRequest() +Example: +

<?php
+$I->sendAjaxRequest('PUT', '/posts/7', ['title' => 'new title']);
+

+

setCookie

+

Signature: setCookie($name, $val, [$params]) : void

+

setHeader

+

Signature: setHeader(string $name, string $value) : void

+

Alias to haveHttpHeader

+

setMaxRedirects

+

Signature: setMaxRedirects(int $maxRedirects) : void

+

Sets the maximum number of redirects that the Client can follow.

+
<?php
+$I->setMaxRedirects(2);
+
+

setServerParameters

+

Signature: setServerParameters(array $params) : void

+

Sets SERVER parameters valid for all next requests. +this will remove old ones.

+
<?php
+$I->setServerParameters([]);
+
+

startFollowingRedirects

+

Signature: startFollowingRedirects() : void

+

Enables automatic redirects to be followed by the client.

+
<?php
+$I->startFollowingRedirects();
+
+

stopFollowingRedirects

+

Signature: stopFollowingRedirects() : void

+

Prevents automatic redirects to be followed by the client.

+
<?php
+$I->stopFollowingRedirects();
+
+

submitForm

+

Signature: submitForm($selector, array $params, [?string $button]) : void

+

switchToIframe

+

Signature: switchToIframe(string $name) : void

+

Switch to iframe or frame on the page.

+

Example: +

<iframe name="another_frame" src="http://example.com">
+

+
<?php
+# switch to iframe
+$I->switchToIframe("another_frame");
+
+

uncheckOption

+

Signature: uncheckOption($option) : void

+ + +

Read more in Codeception documentation.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/WPCLI/index.html b/modules/WPCLI/index.html new file mode 100644 index 000000000..403b1ec6a --- /dev/null +++ b/modules/WPCLI/index.html @@ -0,0 +1,3442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPCLI - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + + + +

WPCLI

+ +

WPCLI module

+

Use WP-CLI to interact with the WordPress installation under test and issue commands.

+

This module is used in the context of end-to-end testing, together with, or as a replacement for +the WPDb module to manipulate the database and the WPFilesystem module to manipulate the +site file structure.

+

This module should be with Cest and Cept test cases.

+

Configuration

+
    +
  • path - required; the path to the WordPress installation under test. This can be a relative path to the + codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation + directory is the directory that contains the wp-load.php file.
  • +
  • url - the URL of the WordPress installation under test. Equivalent to the --url option of the wp command.
  • +
  • user - the user to use to run the wp command. Equivalent to the --user option of the wp command.
  • +
  • skip-plugins - a boolean value to indicate if the wp command should skip loading plugins. Equivalent to the + --skip-plugins option of the wp command.
  • +
  • skip-themes - a boolean value to indicate if the wp command should skip loading themes. Equivalent to the + --skip-themes option of the wp command.
  • +
  • skip-packages - a boolean value to indicate if the wp command should skip loading packages. Equivalent to the + --skip-packages option of the wp command.
  • +
  • require - a list of PHP files to require before running the wp command. Equivalent to the --require option of + the wp command.
  • +
  • exec - PHP code to execute before running the wp command. Equivalent to the --exec option of the wp command.
  • +
  • context - the context to use when running the wp command. Equivalent to the --context option of the wp + command.
  • +
  • color - a boolean value to indicate if the wp command should output in color. Equivalent to the --color option + of the wp command.
  • +
  • no-color - a boolean value to indicate if the wp command should not output in color. Equivalent to the + --no-color option of the wp command.
  • +
  • debug - a boolean value to indicate if the wp command should output debug information. Equivalent to the + --debug option of the wp command.
  • +
  • quiet - a boolean value to indicate if the wp command should suppress informational messages. Equivalent to the + --quiet option of the wp command.
  • +
  • throw - a boolean value to indicate if the wp command should throw an exception if the command fails.
  • +
  • timeout - the timeout to use when running the wp command. When the timeout is reached the command will be + terminated as a failure.
  • +
  • cache-dir - the directory to use to cache the files WPCLI might downloads. Equivalent to setting + the WP_CLI_CACHE_DIR + environment variable.
  • +
  • config-path - the path to the wp-cli.yml file to use. Equivalent to setting the WP_CLI_CONFIG_PATH + environment variable.
  • +
  • custom-shell - the shell to use to run the wp command. Equivalent to setting the WP_CLI_SHELL environment + variable.
  • +
  • packages-dir - the directory to use to store the packages downloaded by the wp package command. Equivalent to + setting the WP_CLI_PACKAGES_DIR environment variable.
  • +
+

The following is an example of the module configuration to run WPCLI commands on the /var/wordpress directory:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPCLI:
+      path: /var/wordpress
+      throw: true
+
+

The following configuration uses dynamic configuration parameters to set the module configuration:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPCLI:
+      path: '%WP_ROOT_DIR%'
+      throw: true
+
+

Methods

+

The module provides the following methods:

+ + +

changeWpcliPath

+

Signature: changeWpcliPath(string $path) : void

+

Changes the path to the WordPress installation that WPCLI should use.

+

This is the equivalent of the --path option.

+
<?php
+// Operate on the installation specified in the `path` config parameter.
+$I->cli(['core','version']);
+// Change to another installation and run a command there.
+$I->changeWpcliPath('var/wordpress-installation-two');
+$I->cli(['core','version']);
+
+

cli

+

Signature: cli([array|string $command], [?array $env], [mixed $input]) : int

+

Executes a wp-cli command targeting the test WordPress installation.

+
<?php
+// Activate a plugin via wp-cli in the test WordPress site.
+$I->cli(['plugin', 'activate', 'my-plugin']);
+// Change a user password.
+$I->cli(['user', 'update', 'luca', '--user_pass=newpassword']);
+
+

cliToArray

+

Signature: cliToArray(array $command, [?callable $splitCallback], [?array $env], [mixed $input]) : array

+

Returns the output of a wp-cli command as an array optionally allowing a callback to process the output.

+
<?php
+// Return a list of inactive themes, like ['twentyfourteen', 'twentyfifteen'].
+$inactiveThemes = $I->cliToArray(['theme', 'list', '--status=inactive', '--field=name']);
+// Get the list of installed plugins and only keep the ones starting with "foo".
+$fooPlugins = $I->cliToArray(['plugin', 'list', '--field=name'], function($output){
+     return array_filter(explode(PHP_EOL, $output), function($name){
+             return strpos(trim($name), 'foo') === 0;
+     });
+});
+
+

cliToString

+

Signature: cliToString(array $command, [?array $env], [mixed $input]) : string

+

Returns the output of a wp-cli command as a string.

+
<?php
+// Return the current site administrator email, using string command format.
+$adminEmail = $I->cliToString('option get admin_email');
+// Get the list of active plugins in JSON format, two ways.
+$activePlugins = $I->cliToString(['plugin', 'list','--status=active', '--format=json']);
+$activePlugins = $I->cliToString(['option', 'get', 'active_plugins' ,'--format=json']);
+
+

dontSeeInShellOutput

+

Signature: dontSeeInShellOutput(string $text) : void

+

Checks that output from last command doesn't contain text.

+
<?php
+// Return the current site administrator email, using string command format.
+$I->cli('plugin list --status=active');
+$I->dontSeeInShellOutput('my-inactive/plugin.php');
+
+

dontSeeShellOutputMatches

+

Signature: dontSeeShellOutputMatches(string $regex) : void

+

Checks that output from the last command doesn't match a given regular expression.

+
<?php
+// Return the current site administrator email, using string command format.
+$I->cli('option get siteurl');
+$I->dontSeeShellOutputMatches('/^http/');
+
+

grabLastCliProcess

+

Signature: grabLastCliProcess() : lucatume\WPBrowser\WordPress\CliProcess

+

grabLastShellErrorOutput

+

Signature: grabLastShellErrorOutput() : string

+

Returns the shell error output of the last command.

+

grabLastShellOutput

+

Signature: grabLastShellOutput() : string

+

Returns the shell output of the last command.

+

seeInShellOutput

+

Signature: seeInShellOutput(string $text) : void

+

Checks that output from last command contains text.

+
<?php
+// Return the current site administrator email, using string command format.
+$I->cli('option get admin_email');
+$I->seeInShellOutput('admin@example.org');
+
+

seeResultCodeIs

+

Signature: seeResultCodeIs(int $code) : void

+

Checks the result code from the last command.

+
<?php
+// Return the current site administrator email, using string command format.
+$I->cli('option get admin_email');
+$I->seeResultCodeIs(0);
+
+

seeResultCodeIsNot

+

Signature: seeResultCodeIsNot(int $code) : void

+

Checks the result code from the last command.

+
<?php
+// Return the current site administrator email, using string command format.
+$I->cli('invalid command');
+$I->seeResultCodeIsNot(0);
+
+

seeShellOutputMatches

+

Signature: seeShellOutputMatches(string $regex) : void

+

Checks that output from the last command matches a given regular expression.

+
<?php
+// Return the current site administrator email, using string command format.
+$I->cli('option get admin_email');
+$I->seeShellOutputMatches('/^\S+@\S+$/');
+
+ + +

Explore the WP-CLI documentation for more information on the available commands.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/WPDb/index.html b/modules/WPDb/index.html new file mode 100644 index 000000000..5d148468b --- /dev/null +++ b/modules/WPDb/index.html @@ -0,0 +1,7805 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPDb - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

WPDb

+ +

WPDb module

+

This module allows to manipulate the database of the WordPress installation under test directly, without using the +WordPress API.

+

The module is used together with the WPBrowser module, WPWebDriver +and WPFilesystem modules to control the site state, the database, and the site file structure.

+

Note about interaction with the WPLoader module: both this module and the WPLoader one can be used to +control the state of the database before tests and set up fixtures: use either this or WPLoader, do not use both. +This module should be used in end-to-end testing, the WPLoader module should be used in integration +testing. +If you're using this module to load a database dump before integration tests, +use the WPLoader module dump configuration parameter instead.

+

This module should be with Cest and Cept test cases.

+

Configuration

+

This module extends the Codeception Db module adding some configuration options and functions that are specific to +WordPress.

+
    +
  • dbUrl - required; the URL to use to connect to the database. The URL must be in the form + mysql://user:password@host:port/database if you're using a MySQL database for your tests, or in the form + sqlite://path/to/database/file if you're using a SQLite database for your tests ( + like the default configuration does)
  • +
  • dsn - required; the DSN to use to connect to the database; required if not using the dbUrl parameter.
  • +
  • user - required; the user to use to connect to the database; required if not using the dbUrl parameter.
  • +
  • password - required; the password to use to connect to the database; required if not using the dbUrl + parameter.
  • +
  • url - required;the URL of the WordPress installation under test. E.g. http://localhost:8080 + or https://wordpress.test.
  • +
  • tablePrefix - the table prefix to use when interacting with the database; defaults to wp_.
  • +
  • dump - the path to a database dump file, or a set of database files, to load before running tests. The path can be + relative to the project root directory, e.g. tests/_data/dump.sql, or absolute.
  • +
  • populate - a boolean value to indicate if the database should be populated importing the dump file(s) at the start + of the suite.
  • +
  • cleanup - a boolean value to indicate if the database should be populated importing the dump file(s) before each + test.
  • +
  • reconnect - a boolean value to indicate if the database connection should be re-established before each test.
  • +
  • populator - a command to use to populate the database instead of using + PHP; read more on the Codeception documentation.
  • +
  • urlReplacement - a boolean value to indicate if the database dump file(s) should be searched for the siteurl + and home options and replaced with the url parameter value. This is required since WordPress hard-codes URLs in + the database, the original URL is inferred, if the originalUrl parameter is not provided.
  • +
  • originalUrl - if provided together with the urlReplacement parameter, the module will not try to infer the + original URL from the database dump file(s) but use the provided value instead.
  • +
  • waitlock - the number of seconds to wait for a database lock to be released before failing the test. Defaults to + 10 meaning that the test will fail if the database lock is not released after 10 seconds.
  • +
  • createIfNotExists - a boolean value to indicate if the database should be created if it does not exist. Defaults to + false.
  • +
+

The following is an example of the module configuration to run tests on thehttp://localhost:8080 site:

+
modules:
+  enabled:
+    - lucatume\WPBrowser\Module\WPDb:
+        dbUrl: 'mysql://root:password@localhost:3306/wordpress'
+        url: 'http://localhost:8080'
+        tablePrefix: 'wp_'
+        dump: 'tests/_data/dump.sql'
+        populate: true
+        cleanup: true
+        reconnect: false
+        urlReplacement: true
+        originalUrl: http://wordpress.test
+        waitlock: 10
+        createIfNotExists: true
+
+

The following configuration uses dynamic configuration parameters to set the module configuration:

+
modules:
+  enabled:
+    - lucatume\WPBrowser\Module\WPDb:
+        dbUrl: '%DB_URL%'
+        url: '%WORDPRESS_URL%'
+        tablePrefix: '%WORDPRESS_TABLE_PREFIX%'
+        dump: '%DB_DUMP%'
+        populate: true
+        cleanup: true
+        reconnect: false
+        urlReplacement: true
+        originalUrl: '%WORDPRESS_ORIGINAL_URL%'
+        waitlock: 10
+        createIfNotExists: true
+
+

The following configuration uses a SQLite database:

+
modules:
+  enabled:
+    - lucatume\WPBrowser\Module\WPDb:
+        dbUrl: 'sqlite://tests/database.sqlite'
+        url: 'http://localhost:8080'
+        tablePrefix: 'wp_'
+        dump: 'tests/_data/dump.sql'
+        populate: true
+        cleanup: true
+        reconnect: false
+        urlReplacement: true
+        originalUrl: http://wordpress.test
+        waitlock: 10
+        createIfNotExists: true
+
+

Methods

+ + +

amConnectedToDatabase

+

Signature: amConnectedToDatabase(string $databaseKey) : void

+

Make sure you are connected to the right database.

+
<?php
+$I->seeNumRecords(2, 'users');   //executed on default database
+$I->amConnectedToDatabase('db_books');
+$I->seeNumRecords(30, 'books');  //executed on db_books database
+//All the next queries will be on db_books
+
+

countRowsInDatabase

+

Signature: countRowsInDatabase(string $table, [array $criteria]) : int

+

Returns the number of table rows matching a criteria.

+
<?php
+$I->haveManyPostsInDatabase(3, ['post_status' => 'draft' ]);
+$I->haveManyPostsInDatabase(3, ['post_status' => 'private' ]);
+// Make sure there are now the expected number of draft posts.
+$postsTable = $I->grabPostsTableName();
+$draftsCount = $I->countRowsInDatabase($postsTable, ['post_status' => 'draft']);
+
+

dontHaveAttachmentFilesInDatabase

+

Signature: dontHaveAttachmentFilesInDatabase(array|int $attachmentIds) : void

+

Removes all the files attached with an attachment post, it will not remove the database entries. +Requires the WPFilesystem module to be loaded in the suite.

+
<?php
+$posts = $I->grabPostsTableName();
+$attachmentIds = $I->grabColumnFromDatabase($posts, 'ID', ['post_type' => 'attachment']);
+// This will only remove the files, not the database entries.
+$I->dontHaveAttachmentFilesInDatabase($attachmentIds);
+
+

dontHaveAttachmentInDatabase

+

Signature: dontHaveAttachmentInDatabase(array $criteria, [bool $purgeMeta], [bool $removeFiles]) : void

+

Removes an attachment from the posts table.

+
$postmeta = $I->grabpostmetatablename();
+$thumbnailId = $I->grabFromDatabase($postmeta, 'meta_value', [
+     'post_id' => $id,
+     'meta_key'=>'thumbnail_id'
+]);
+// Remove only the database entry (including postmeta) but not the files.
+$I->dontHaveAttachmentInDatabase($thumbnailId);
+// Remove the database entry (including postmeta) and the files.
+$I->dontHaveAttachmentInDatabase($thumbnailId, true, true);
+
+

dontHaveBlogInDatabase

+

Signature: dontHaveBlogInDatabase(array $criteria, [bool $removeTables], [bool $removeUploads]) : void

+

Removes one ore more blogs from the database.

+
<?php
+// Remove the blog, all its tables and files.
+$I->dontHaveBlogInDatabase(['path' => 'test/one']);
+// Remove the blog entry, not the tables though.
+$I->dontHaveBlogInDatabase(['blog_id' => $blogId]);
+// Remove multiple blogs.
+$I->dontHaveBlogInDatabase(['domain' => 'test']);
+
+

dontHaveCommentInDatabase

+

Signature: dontHaveCommentInDatabase(array $criteria, [bool $purgeMeta]) : void

+

Removes an entry from the comments table.

+
<?php
+$I->dontHaveCommentInDatabase(['comment_post_ID' => 23, 'comment_url' => 'http://example.copm']);
+
+

dontHaveCommentMetaInDatabase

+

Signature: dontHaveCommentMetaInDatabase(array $criteria) : void

+

Removes a post comment meta from the database

+
<?php
+// Remove all meta for the comment with an ID of 23.
+$I->dontHaveCommentMetaInDatabase(['comment_id' => 23]);
+// Remove the `count` comment meta for the comment with an ID of 23.
+$I->dontHaveCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'count']);
+
+

dontHaveInDatabase

+

Signature: dontHaveInDatabase(string $table, array $criteria) : void

+

Deletes a database entry.

+
<?php
+$I->dontHaveInDatabase('custom_table', ['book_ID' => 23, 'book_genre' => 'fiction']);
+
+

dontHaveLinkInDatabase

+

Signature: dontHaveLinkInDatabase(array $criteria) : void

+

Removes a link from the database.

+
<?php
+$I->dontHaveLinkInDatabase(['link_url' => 'http://example.com']);
+
+

dontHaveOptionInDatabase

+

Signature: dontHaveOptionInDatabase(string $key, [mixed $value]) : void

+

Removes an entry from the options table.

+
<?php
+// Remove the `foo` option.
+$I->dontHaveOptionInDatabase('foo');
+// Remove the 'bar' option only if it has the `baz` value.
+$I->dontHaveOptionInDatabase('bar', 'baz');
+
+

dontHavePostInDatabase

+

Signature: dontHavePostInDatabase(array $criteria, [bool $purgeMeta]) : void

+

Removes an entry from the posts table.

+
<?php
+$posts = $I->haveManyPostsInDatabase(3, ['post_title' => 'Test {{n}}']);
+$I->dontHavePostInDatabase(['post_title' => 'Test 2']);
+
+

dontHavePostMetaInDatabase

+

Signature: dontHavePostMetaInDatabase(array $criteria) : void

+

Removes an entry from the postmeta table.

+
<?php
+$postId = $I->havePostInDatabase(['meta_input' => ['rating' => 23]]);
+$I->dontHavePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'rating']);
+
+

dontHavePostThumbnailInDatabase

+

Signature: dontHavePostThumbnailInDatabase(int $postId) : void

+

Remove the thumbnail (featured image) from a post, if any.

+

Please note: the method will NOT remove the attachment post, post meta and file.

+
<?php
+$attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));
+$postId = $I->havePostInDatabase();
+// Attach the thumbnail to the post.
+$I->havePostThumbnailInDatabase($postId, $attachmentId);
+// Remove the thumbnail from the post.
+$I->dontHavePostThumbnailInDatabase($postId);
+
+

dontHaveSiteOptionInDatabase

+

Signature: dontHaveSiteOptionInDatabase(string $key, [mixed $value]) : void

+

Removes a site option from the database.

+
<?php
+// Remove the `foo_count` option.
+$I->dontHaveSiteOptionInDatabase('foo_count');
+// Remove the `foo_count` option only if its value is `23`.
+$I->dontHaveSiteOptionInDatabase('foo_count', 23);
+
+

dontHaveSiteTransientInDatabase

+

Signature: dontHaveSiteTransientInDatabase(string $key) : void

+

Removes a site transient from the database.

+
<?php
+$I->dontHaveSiteTransientInDatabase(['my_plugin_site_buffer']);
+
+

dontHaveTableInDatabase

+

Signature: dontHaveTableInDatabase(string $fullTableName) : void

+

Removes a table from the database. +The case where a table does not exist is handled without raising an error.

+
<?php
+$ordersTable = $I->grabPrefixedTableNameFor('orders');
+$I->dontHaveTableInDatabase($ordersTable);
+
+

dontHaveTermInDatabase

+

Signature: dontHaveTermInDatabase(array $criteria, [bool $purgeMeta]) : void

+

Removes a term from the database.

+
<?php
+$I->dontHaveTermInDatabase(['name' => 'romance']);
+$I->dontHaveTermInDatabase(['slug' => 'genre--romance']);
+
+

dontHaveTermMetaInDatabase

+

Signature: dontHaveTermMetaInDatabase(array $criteria) : void

+

Removes a term meta from the database.

+
<?php
+// Remove the "karma" key.
+$I->dontHaveTermMetaInDatabase(['term_id' => $termId, 'meta_key' => 'karma']);
+// Remove all meta for the term.
+$I->dontHaveTermMetaInDatabase(['term_id' => $termId]);
+
+

dontHaveTermRelationshipInDatabase

+

Signature: dontHaveTermRelationshipInDatabase(array $criteria) : void

+

Removes an entry from the term_relationships table.

+
<?php
+// Remove the relation between a post and a category.
+$I->dontHaveTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $ttaxId]);
+// Remove all terms for a post.
+$I->dontHaveTermMetaInDatabase(['object_id' => $postId]);
+
+

dontHaveTermTaxonomyInDatabase

+

Signature: dontHaveTermTaxonomyInDatabase(array $criteria) : void

+

Removes an entry from the term_taxonomy table.

+
<?php
+// Remove a specific term from the genre taxonomy.
+$I->dontHaveTermTaxonomyInDatabase(['term_id' => $postId, 'taxonomy' => 'genre']);
+// Remove all terms for a taxonomy.
+$I->dontHaveTermTaxonomyInDatabase(['taxonomy' => 'genre']);
+
+

dontHaveTransientInDatabase

+

Signature: dontHaveTransientInDatabase(string $transient) : void

+

Removes a transient from the database.

+
<?php
+// Removes the `tweets` transient from the database, if set.
+$I->dontHaveTransientInDatabase('tweets');
+
+

dontHaveUserInDatabase

+

Signature: dontHaveUserInDatabase(string|int $userIdOrLogin, [bool $purgeMeta]) : void

+

Removes a user from the database.

+
<?php
+$bob = $I->haveUserInDatabase('bob');
+$alice = $I->haveUserInDatabase('alice');
+// Remove Bob's user and meta.
+$I->dontHaveUserInDatabase('bob');
+// Remove Alice's user but not meta.
+$I->dontHaveUserInDatabase($alice);
+
+

dontHaveUserInDatabaseWithEmail

+

Signature: dontHaveUserInDatabaseWithEmail(string $userEmail, [bool $purgeMeta]) : array

+

Removes a user(s) from the database using the user email address.

+
<?php
+$luca = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);
+$I->dontHaveUserInDatabaseWithEmail('luca@exampl.org');
+
+

dontHaveUserMetaInDatabase

+

Signature: dontHaveUserMetaInDatabase(array $criteria) : void

+

Removes an entry from the usermeta table.

+
<?php
+// Remove the `karma` user meta for a user.
+$I->dontHaveUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);
+// Remove all the user meta for a user.
+$I->dontHaveUserMetaInDatabase(['user_id' => 23]);
+
+

dontSeeAttachmentInDatabase

+

Signature: dontSeeAttachmentInDatabase(array $criteria) : void

+

Checks that an attachment is not in the database.

+
<?php
+$url = 'https://example.org/images/foo.png';
+$I->dontSeeAttachmentInDatabase(['guid' => $url]);
+
+

dontSeeBlogInDatabase

+

Signature: dontSeeBlogInDatabase(array $criteria) : void

+

Checks that a row is not present in the blogs table.

+
<?php
+$I->haveManyBlogsInDatabase(2, ['path' => 'test-{{n}}'], false)
+$I->dontSeeBlogInDatabase(['path' => '/test-3/'])
+
+

dontSeeCommentInDatabase

+

Signature: dontSeeCommentInDatabase(array $criteria) : void

+

Checks that a comment is not in the database.

+

Will look up the "comments" table.

+
<?php
+// Checks for one comment.
+$I->dontSeeCommentInDatabase(['comment_ID' => 23]);
+// Checks for comments from a user.
+$I->dontSeeCommentInDatabase(['user_id' => 89]);
+
+

dontSeeCommentMetaInDatabase

+

Signature: dontSeeCommentMetaInDatabase(array $criteria) : void

+

Checks that a comment meta value is not in the database.

+

Will look up the "commentmeta" table.

+
<?php
+// Delete a comment `karma` meta.
+$I->dontSeeCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'karma']);
+// Delete all meta for a comment.
+$I->dontSeeCommentMetaInDatabase(['comment_id' => 23]);
+
+

dontSeeInDatabase

+

Signature: dontSeeInDatabase(string $table, [array $criteria]) : void

+

dontSeeLinkInDatabase

+

Signature: dontSeeLinkInDatabase(array $criteria) : void

+

Checks that a link is not in the links database table.

+
<?php
+$I->dontSeeLinkInDatabase(['link_url' => 'http://example.com']);
+$I->dontSeeLinkInDatabase(['link_url' => 'http://example.com', 'link_name' => 'example']);
+
+

dontSeeOptionInDatabase

+

Signature: dontSeeOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

+

Checks that an option is not in the database for the current blog.

+

If the value is an object or an array then the serialized option will be checked.

+
<?php
+$I->dontHaveOptionInDatabase('posts_per_page');
+$I->dontSeeOptionInDatabase('posts_per_page');
+$I->dontSeeOptionInDatabase('posts_per_page', 23);
+$I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page']);
+$I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page', 'option_value' => 23]);
+
+

dontSeePageInDatabase

+

Signature: dontSeePageInDatabase(array $criteria) : void

+

Checks that a page is not in the database.

+
<?php
+// Assert a page with an ID does not exist.
+$I->dontSeePageInDatabase(['ID' => 23]);
+// Assert a page with a slug and ID.
+$I->dontSeePageInDatabase(['post_name' => 'test', 'ID' => 23]);
+
+

dontSeePostInDatabase

+

Signature: dontSeePostInDatabase(array $criteria) : void

+

Checks that a post is not in the database.

+
<?php
+// Asserts a post with title 'Test' is not in the database.
+$I->dontSeePostInDatabase(['post_title' => 'Test']);
+// Asserts a post with title 'Test' and content 'Test content' is not in the database.
+$I->dontSeePostInDatabase(['post_title' => 'Test', 'post_content' => 'Test content']);
+
+

dontSeePostMetaInDatabase

+

Signature: dontSeePostMetaInDatabase(array $criteria) : void

+

Checks that a post meta value does not exist.

+

If the meta value is an object or an array then the check will be made on its serialized version.

+
<?php
+$postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']]);
+$I->dontSeePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'woot']);
+
+

dontSeePostWithTermInDatabase

+

Signature: dontSeePostWithTermInDatabase(int $post_id, int $term_taxonomy_id, [?int $term_order], [?string $taxonomy]) : void

+

Checks that a post to term relation does not exist in the database.

+

The method will check the "term_relationships" table.

+
<?php
+$fiction = $I->haveTermInDatabase('fiction', 'genre');
+$nonFiction = $I->haveTermInDatabase('non-fiction', 'genre');
+$postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);
+$I->dontSeePostWithTermInDatabase($postId, $nonFiction['term_taxonomy_id], );
+
+

dontSeeSiteOptionInDatabase

+

Signature: dontSeeSiteOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

+

Checks that a site option is not in the database.

+
<?php
+// Check that the option is not set in the database.
+$I->dontSeeSiteOptionInDatabase('foo_count');
+// Check that the option is not set with a specific value.
+$I->dontSeeSiteOptionInDatabase('foo_count', 23);
+$I->dontSeeSiteOptionInDatabase(['option_name => 'foo_count', 'option_value' => 23]);
+
+

dontSeeSiteTransientInDatabase

+

Signature: dontSeeSiteTransientInDatabase(string $transient, [mixed $value]) : void

+

Checks that a site transient is not in the database.

+
<?php
+$I->dontSeeSiteTransientInDatabase('foo');
+$I->dontSeeSiteTransientInDatabase('foo', 23);
+
+

dontSeeTableInDatabase

+

Signature: dontSeeTableInDatabase(string $table) : void

+

Checks that a table is not in the database.

+
<?php
+$options = $I->grabPrefixedTableNameFor('options');
+$I->dontHaveTableInDatabase($options)
+$I->dontSeeTableInDatabase($options);
+
+

dontSeeTermInDatabase

+

Signature: dontSeeTermInDatabase(array $criteria) : void

+

Makes sure a term is not in the database.

+

Looks up both the terms table and the term_taxonomy tables.

+
<?php
+// Asserts a 'fiction' term is not in the database.
+$I->dontSeeTermInDatabase(['name' => 'fiction']);
+// Asserts a 'fiction' term with slug 'genre--fiction' is not in the database.
+$I->dontSeeTermInDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);
+
+

dontSeeTermMetaInDatabase

+

Signature: dontSeeTermMetaInDatabase(array $criteria) : void

+

Checks that a term meta is not in the database.

+
<?php
+list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
+$I->haveTermMetaInDatabase($termId, 'rating', 4);
+$I->dontSeeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'average_review']);
+
+

dontSeeTermTaxonomyInDatabase

+

Signature: dontSeeTermTaxonomyInDatabase(array $criteria) : void

+

Checks that a term taxonomy is not in the database.

+
<?php
+list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
+$I->dontSeeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'country']);
+
+

dontSeeTransientInDatabase

+

Signature: dontSeeTransientInDatabase(string $transient, [mixed $value]) : void

+

Checks that a transient is not in the database.

+
<?php
+$I->dontSeeTransientInDatabase('foo');
+$I->dontSeeTransientInDatabase('foo', 23);
+
+

dontSeeUserInDatabase

+

Signature: dontSeeUserInDatabase(array $criteria) : void

+

Checks that a user is not in the database.

+
<?php
+// Asserts a user does not exist in the database.
+$I->dontSeeUserInDatabase(['user_login' => 'luca']);
+// Asserts a user with email and login is not in the database.
+$I->dontSeeUserInDatabase(['user_login' => 'luca', 'user_email' => 'luca@theaveragedev.com']);
+
+

dontSeeUserMetaInDatabase

+

Signature: dontSeeUserMetaInDatabase(array $criteria) : void

+

Check that a user meta value is not in the database.

+
<?php
+// Asserts a user does not have a 'karma' meta assigned.
+$I->dontSeeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);
+// Asserts no user has any 'karma' meta assigned.
+$I->dontSeeUserMetaInDatabase(['meta_key' => 'karma']);
+
+

getSiteDomain

+

Signature: getSiteDomain() : string

+

Returns the site domain inferred from the url set in the config.

+
<?php
+$domain = $I->getSiteDomain();
+// We should be redirected to the HTTPS version when visiting the HTTP version.
+$I->amOnPage('http://' . $domain);
+$I->seeCurrentUrlEquals('https://' . $domain);
+
+

getUsersTableName

+

Signature: getUsersTableName() : string

+

Returns the prefixed users table name.

+
<?php
+// Given a `wp_` table prefix returns `wp_users`.
+$usersTable = $I->getUsersTableName();
+// Given a `wp_` table prefix returns `wp_users`.
+$I->useBlog(23);
+$usersTable = $I->getUsersTableName();
+
+

grabAllFromDatabase

+

Signature: grabAllFromDatabase(string $table, string $column, array $criteria) : array

+

Returns all entries matching a criteria from the database.

+
<?php
+$books = $I->grabPrefixedTableNameFor('books');
+$I->grabAllFromDatabase($books, 'title', ['genre' => 'fiction']);
+
+

grabAttachmentAttachedFile

+

Signature: grabAttachmentAttachedFile(int $attachmentPostId) : string

+

Returns the path, as stored in the database, of an attachment _wp_attached_file meta. +The attached file is, usually, an attachment origal file.

+
<?php
+$file = $I->grabAttachmentAttachedFile($attachmentId);
+$fileInfo = new SplFileInfo($file);
+$I->assertEquals('jpg', $fileInfo->getExtension());
+
+

grabAttachmentMetadata

+

Signature: grabAttachmentMetadata(int $attachmentPostId) : array

+

Returns the metadata array for an attachment post. +This is the value of the _wp_attachment_metadata meta.

+
<?php
+$metadata = $I->grabAttachmentMetadata($attachmentId);
+$I->assertEquals(['thumbnail', 'medium', 'medium_large'], array_keys($metadata['sizes']);
+
+

grabBlogDomain

+

Signature: grabBlogDomain(int $blogId) : string

+

Returns a blog domain given its ID.

+
<?php
+$blogIds = $I->haveManyBlogsInDatabase(3);
+$domains = array_map(function($blogId){
+     return $I->grabBlogDomain($blogId);
+}, $blogIds);
+
+

grabBlogPath

+

Signature: grabBlogPath(int $blogId) : string

+

Grabs a blog domain from the blogs table.

+
<?php
+$blogId = $I->haveBlogInDatabase('test');
+$path = $I->grabBlogDomain($blogId);
+$I->amOnSubdomain($path);
+$I->amOnPage('/');
+
+

grabBlogTableName

+

Signature: grabBlogTableName(int $blogId, string $table) : string

+

Returns the full name of a table for a blog from a multisite installation database.

+
<?php
+$blogOptionTable = $I->grabBlogTableName($blogId, 'option');
+
+

grabBlogTableNames

+

Signature: grabBlogTableNames(int $blogId) : array

+

Returns a list of tables for a blog ID.

+
<?php
+     $blogId = $I->haveBlogInDatabase('test');
+     $tables = $I->grabBlogTableNames($blogId);
+     $options = array_filter($tables, function($tableName){
+     return str_pos($tableName, 'options') !== false;
+});
+
+

grabBlogTablePrefix

+

Signature: grabBlogTablePrefix(int $blogId) : string

+

Returns the table prefix for a blog.

+
<?php
+$blogId = $I->haveBlogInDatabase('test');
+$blogTablePrefix = $I->getBlogTablePrefix($blogId);
+$blogOrders = $I->blogTablePrefix . 'orders';
+
+

grabBlogUrl

+

Signature: grabBlogUrl([int $blogId]) : string

+

Gets the blog URL from the Blog ID.

+

grabBlogVersionsTableName

+

Signature: grabBlogVersionsTableName() : string

+

Gets the prefixed blog_versions table name.

+
<?php
+// Assuming a `wp_` table prefix it will return `wp_blog_versions`.
+$blogVersionsTable = $I->grabBlogVersionsTableName();
+$I->useBlog(23);
+// Assuming a `wp_` table prefix it will return `wp_blog_versions`.
+$blogVersionsTable = $I->grabBlogVersionsTableName();
+
+

grabBlogsTableName

+

Signature: grabBlogsTableName() : string

+

Gets the prefixed blogs table name.

+
<?php
+// Assuming a `wp_` table prefix it will return `wp_blogs`.
+$blogVersionsTable = $I->grabBlogsTableName();
+$I->useBlog(23);
+// Assuming a `wp_` table prefix it will return `wp_blogs`.
+$blogVersionsTable = $I->grabBlogsTableName();
+
+

grabColumnFromDatabase

+

Signature: grabColumnFromDatabase(string $table, string $column, [array $criteria]) : array

+

Fetches all values from the column in database. +Provide table name, desired column and criteria.

+
<?php
+$mails = $I->grabColumnFromDatabase('users', 'email', array('name' => 'RebOOter'));
+
+

grabCommentmetaTableName

+

Signature: grabCommentmetaTableName() : string

+

Returns the prefixed comment meta table name.

+
<?php
+// Get all the values of 'karma' for all comments.
+$commentMeta = $I->grabCommentmetaTableName();
+$I->grabAllFromDatabase($commentMeta, 'meta_value', ['meta_key' => 'karma']);
+
+

grabCommentsTableName

+

Signature: grabCommentsTableName() : string

+

Gets the comments table name.

+
<?php
+// Will be `wp_comments`.
+$comments = $I->grabCommentsTableName();
+// Will be `wp_23_comments`.
+$I->useBlog(23);
+$comments = $I->grabCommentsTableName();
+
+

grabEntriesFromDatabase

+

Signature: grabEntriesFromDatabase(string $table, [array $criteria]) : array

+

Fetches a set of entries from a database. +Provide table name and criteria.

+

<?php
+$mail = $I->grabEntriesFromDatabase('users', array('name' => 'Davert'));
+
+Comparison expressions can be used as well:

+
<?php
+$post = $I->grabEntriesFromDatabase('posts', ['num_comments >=' => 100]);
+$user = $I->grabEntriesFromDatabase('users', ['email like' => 'miles%']);
+
+

Supported operators: <, >, >=, <=, !=, like.

+

grabEntryFromDatabase

+

Signature: grabEntryFromDatabase(string $table, [array $criteria]) : array

+

Fetches a whole entry from a database. +Make the test fail if the entry is not found. +Provide table name, desired column and criteria.

+

<?php
+$mail = $I->grabEntryFromDatabase('users', array('name' => 'Davert'));
+
+Comparison expressions can be used as well:

+
<?php
+$post = $I->grabEntryFromDatabase('posts', ['num_comments >=' => 100]);
+$user = $I->grabEntryFromDatabase('users', ['email like' => 'miles%']);
+
+

Supported operators: <, >, >=, <=, !=, like.

+

grabFromDatabase

+

Signature: grabFromDatabase(string $table, string $column, [array $criteria]) : void

+

Fetches a single column value from a database. +Provide table name, desired column and criteria.

+

<?php
+$mail = $I->grabFromDatabase('users', 'email', array('name' => 'Davert'));
+
+Comparison expressions can be used as well:

+
<?php
+$postNum = $I->grabFromDatabase('posts', 'num_comments', ['num_comments >=' => 100]);
+$mail = $I->grabFromDatabase('users', 'email', ['email like' => 'miles%']);
+
+

Supported operators: <, >, >=, <=, !=, like.

+

grabLatestEntryByFromDatabase

+

Signature: grabLatestEntryByFromDatabase(string $tableName, [string $idColumn]) : int

+

Returns the id value of the last table entry.

+
<?php
+$I->haveManyPostsInDatabase();
+$postsTable = $I->grabPostsTableName();
+$last = $I->grabLatestEntryByFromDatabase($postsTable, 'ID');
+
+

grabLinksTableName

+

Signature: grabLinksTableName() : string

+

Returns the prefixed links table name.

+
<?php
+// Given a `wp_` table prefix returns `wp_links`.
+$linksTable = $I->grabLinksTableName();
+// Given a `wp_` table prefix returns `wp_23_links`.
+$I->useBlog(23);
+$linksTable = $I->grabLinksTableName();
+
+

grabNumRecords

+

Signature: grabNumRecords(string $table, [array $criteria]) : int

+

Returns the number of rows in a database

+

grabOptionFromDatabase

+

Signature: grabOptionFromDatabase(string $option_name) : mixed

+

Gets an option value from the database.

+
<?php
+$count = $I->grabOptionFromDatabase('foo_count');
+
+

grabPostFieldFromDatabase

+

Signature: grabPostFieldFromDatabase(int $postId, string $field) : mixed

+

Returns the value of a post field for a post, from the posts table.

+
<?php
+$title = $I->grabPostFieldFromDatabase(1, 'post_title');
+$type = $I->grabPostFieldFromDatabase(1, 'post_type');
+
+

grabPostMetaFromDatabase

+

Signature: grabPostMetaFromDatabase(int $postId, string $metaKey, [bool $single]) : mixed

+

Gets the value of one or more post meta values from the database.

+
<?php
+$thumbnail_id = $I->grabPostMetaFromDatabase($postId, '_thumbnail_id', true);
+
+

grabPostmetaTableName

+

Signature: grabPostmetaTableName() : string

+

Returns the prefixed post meta table name.

+
<?php
+// Returns 'wp_postmeta'.
+$I->grabPostmetaTableName();
+// Returns 'wp_23_postmeta'.
+$I->useBlog(23);
+$I->grabPostmetaTableName();
+
+

grabPostsTableName

+

Signature: grabPostsTableName() : string

+

Gets the posts prefixed table name.

+
<?php
+// Given a `wp_` table prefix returns `wp_posts`.
+$postsTable = $I->grabPostsTableName();
+// Given a `wp_` table prefix returns `wp_23_posts`.
+$I->useBlog(23);
+$postsTable = $I->grabPostsTableName();
+
+

grabPrefixedTableNameFor

+

Signature: grabPrefixedTableNameFor([string $tableName]) : string

+

Returns a prefixed table name for the current blog.

+

If the table is not one to be prefixed (e.g. users) then the proper table name will be returned.

+
<?php
+// Will return wp_users.
+$usersTable = $I->grabPrefixedTableNameFor('users');
+// Will return wp_options.
+$optionsTable = $I->grabPrefixedTableNameFor('options');
+// Use a different blog and get its options table.
+$I->useBlog(2);
+$blogOptionsTable = $I->grabPrefixedTableNameFor('options');
+
+

grabRegistrationLogTableName

+

Signature: grabRegistrationLogTableName() : string

+

Gets the prefixed registration_log table name.

+
<?php
+// Assuming a `wp_` table prefix it will return `wp_registration_log`.
+$blogVersionsTable = $I->grabRegistrationLogTableName();
+$I->useBlog(23);
+// Assuming a `wp_` table prefix it will return `wp_registration_log`.
+$blogVersionsTable = $I->grabRegistrationLogTableName();
+
+

grabSignupsTableName

+

Signature: grabSignupsTableName() : string

+

Gets the prefixed signups table name.

+
<?php
+// Assuming a `wp_` table prefix it will return `wp_signups`.
+$blogVersionsTable = $I->grabSignupsTableName();
+$I->useBlog(23);
+// Assuming a `wp_` table prefix it will return `wp_signups`.
+$blogVersionsTable = $I->grabSignupsTableName();
+
+

grabSiteMetaFromDatabase

+

Signature: grabSiteMetaFromDatabase(int $blogId, string $key, bool $single) : mixed

+

Returns a single or all meta values for a site meta key.

+
<?php
+$I->haveSiteMetaInDatabase(1, 'foo', 'bar');
+$value = $I->grabSiteMetaFromDatabase(1, 'foo', true);
+$values = $I->grabSiteMetaFromDatabase(1, 'foo', false);
+
+

grabSiteMetaTableName

+

Signature: grabSiteMetaTableName() : string

+

Gets the prefixed sitemeta table name.

+
<?php
+// Assuming a `wp_` table prefix it will return `wp_sitemeta`.
+$blogVersionsTable = $I->grabSiteMetaTableName();
+$I->useBlog(23);
+// Assuming a `wp_` table prefix it will return `wp_sitemeta`.
+$blogVersionsTable = $I->grabSiteMetaTableName();
+
+

grabSiteOptionFromDatabase

+

Signature: grabSiteOptionFromDatabase(string $key) : mixed

+

Gets a site option from the database.

+
<?php
+$fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');
+
+

grabSiteTableName

+

Signature: grabSiteTableName() : string

+

Gets the prefixed site table name.

+
<?php
+// Assuming a `wp_` table prefix it will return `wp_site`.
+$blogVersionsTable = $I->grabSiteTableName();
+$I->useBlog(23);
+// Assuming a `wp_` table prefix it will return `wp_site`.
+$blogVersionsTable = $I->grabSiteTableName();
+
+

grabSiteTransientFromDatabase

+

Signature: grabSiteTransientFromDatabase(string $key) : mixed

+

Gets a site transient from the database.

+
<?php
+$I->grabSiteTransientFromDatabase('total_comments');
+$I->grabSiteTransientFromDatabase('api_data');
+
+

grabSiteUrl

+

Signature: grabSiteUrl([?string $path]) : string

+

Returns the current site URL as specified in the module configuration.

+
<?php
+$shopPath = $I->grabSiteUrl('/shop');
+
+

grabTablePrefix

+

Signature: grabTablePrefix() : string

+

Returns the table prefix, namespaced for secondary blogs if selected.

+
<?php
+// Assuming a table prefix of `wp_` it will return `wp_`;
+$tablePrefix = $I->grabTablePrefix();
+$I->useBlog(23);
+// Assuming a table prefix of `wp_` it will return `wp_23_`;
+$tablePrefix = $I->grabTablePrefix();
+
+

grabTermIdFromDatabase

+

Signature: grabTermIdFromDatabase(array $criteria) : int|false

+

Gets a term ID from the database. +Looks up the prefixed terms table, e.g. wp_terms.

+
<?php
+// Return the 'fiction' term 'term_id'.
+$termId = $I->grabTermIdFromDatabase(['name' => 'fiction']);
+// Get a term ID by more stringent criteria.
+$termId = $I->grabTermIdFromDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);
+// Return the 'term_id' of the first term for a group.
+$termId = $I->grabTermIdFromDatabase(['term_group' => 23]);
+
+

grabTermMetaTableName

+

Signature: grabTermMetaTableName() : string

+

Gets the terms meta table prefixed name.

+
<?php
+// Returns 'wp_termmeta'.
+$I->grabTermMetaTableName();
+// Returns 'wp_23_termmeta'.
+$I->useBlog(23);
+$I->grabTermMetaTableName();
+
+

grabTermRelationshipsTableName

+

Signature: grabTermRelationshipsTableName() : string

+

Gets the prefixed term relationships table name, e.g. wp_term_relationships.

+
<?php
+$I->grabTermRelationshipsTableName();
+
+

grabTermTaxonomyIdFromDatabase

+

Signature: grabTermTaxonomyIdFromDatabase(array $criteria) : int|false

+

Gets a term_taxonomy_id from the database.

+

Looks up the prefixed terms_relationships table, e.g. wp_term_relationships.

+
<?php
+// Get the `term_taxonomy_id` for a term and a taxonomy.
+$I->grabTermTaxonomyIdFromDatabase(['term_id' => $fictionId, 'taxonomy' => 'genre']);
+// Get the `term_taxonomy_id` for the first term with a count of 23.
+$I->grabTermTaxonomyIdFromDatabase(['count' => 23]);
+
+

grabTermTaxonomyTableName

+

Signature: grabTermTaxonomyTableName() : string

+

Gets the prefixed term and taxonomy table name, e.g. wp_term_taxonomy.

+
<?php
+// Returns 'wp_term_taxonomy'.
+$I->grabTermTaxonomyTableName();
+// Returns 'wp_23_term_taxonomy'.
+$I->useBlog(23);
+$I->grabTermTaxonomyTableName();
+
+

grabTermsTableName

+

Signature: grabTermsTableName() : string

+

Gets the prefixed terms table name, e.g. wp_terms.

+
<?php
+// Returns 'wp_terms'.
+$I->grabTermsTableName();
+// Returns 'wp_23_terms'.
+$I->useBlog(23);
+$I->grabTermsTableName();
+
+

grabTransientFromDatabase

+

Signature: grabTransientFromDatabase(string $transient) : mixed

+

Fetches the value of a transient from the database.

+
<?php
+$I->haveTransientInDatabase('foo', 23);
+$transientValue = $I->grabTransientFromDatabase('foo');
+$I->assertEquals(23, $transientValue);
+
+

grabUserIdFromDatabase

+

Signature: grabUserIdFromDatabase(string $userLogin) : int|false

+

Gets the a user ID from the database using the user login.

+
<?php
+$userId = $I->grabUserIdFromDatabase('luca');
+
+

grabUserMetaFromDatabase

+

Signature: grabUserMetaFromDatabase(int $userId, string $meta_key, [bool $single]) : mixed

+

Gets a user meta from the database.

+
<?php
+// Returns a user 'karma' value.
+$I->grabUserMetaFromDatabase($userId, 'karma');
+// Returns an array, the unserialized version of the value stored in the database.
+$I->grabUserMetaFromDatabase($userId, 'api_data');
+
+

grabUsermetaTableName

+

Signature: grabUsermetaTableName() : string

+

Returns the prefixed users meta table name.

+
<?php
+// Given a `wp_` table prefix returns `wp_usermeta`.
+$usermetaTable = $I->grabUsermetaTableName();
+// Given a `wp_` table prefix returns `wp_usermeta`.
+$I->useBlog(23);
+$usermetaTable = $I->grabUsermetaTableName();
+
+

grabUsersTableName

+

Signature: grabUsersTableName() : string

+

Returns the prefixed users table name.

+
<?php
+// Given a `wp_` table prefix returns `wp_users`.
+$usersTable = $I->grabUsersTableName();
+// Given a `wp_` table prefix returns `wp_users`.
+$I->useBlog(23);
+$usersTable = $I->grabUsersTableName();
+
+

haveAttachmentInDatabase

+

Signature: haveAttachmentInDatabase(string $file, [string|int $date], [array $overrides], [?array $imageSizes]) : int

+

Creates the database entries representing an attachment and moves the attachment file to the right location.

+
<?php
+$file = codecept_data_dir('images/test.png');
+$attachmentId = $I->haveAttachmentInDatabase($file);
+$image = codecept_data_dir('images/test-2.png');
+$lastWeekAttachment = $I->haveAttachmentInDatabase($image, '-1 week');
+
+

Requires the WPFilesystem module.

+

haveBlogInDatabase

+

Signature: haveBlogInDatabase(string $domainOrPath, [array $overrides], [bool $subdomain]) : int

+

Inserts a blog in the blogs table.

+
<?php
+// Create the `test` subdomain blog.
+$blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId]);
+// Create the `/test` subfolder blog.
+$blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId], false);
+
+

haveCommentInDatabase

+

Signature: haveCommentInDatabase(int $comment_post_ID, [array $data]) : int

+

Inserts a comment in the database.

+
<?php
+$I->haveCommentInDatabase($postId, ['comment_content' => 'Test Comment', 'comment_karma' => 23]);
+
+

haveCommentMetaInDatabase

+

Signature: haveCommentMetaInDatabase(int $comment_id, string $meta_key, mixed $meta_value) : int

+

Inserts a comment meta field in the database. +Array and object meta values will be serialized.

+
<?php
+$I->haveCommentMetaInDatabase($commentId, 'api_ID', 23);
+// The value will be serialized.
+$apiData = ['ID' => 23, 'user' => 89, 'origin' => 'twitter'];
+$I->haveCommentMetaInDatabase($commentId, 'api_data', $apiData);
+
+

haveInDatabase

+

Signature: haveInDatabase(string $table, array $data) : int

+

Inserts an SQL record into a database. This record will be erased after the test, +unless you've configured "skip_cleanup_if_failed", and the test fails.

+
<?php
+$I->haveInDatabase('users', array('name' => 'miles', 'email' => 'miles@davis.com'));
+
+

haveLinkInDatabase

+

Signature: haveLinkInDatabase([array $overrides]) : int

+

Inserts a link in the database.

+
<?php
+$linkId = $I->haveLinkInDatabase(['link_url' => 'http://example.org']);
+
+

haveManyBlogsInDatabase

+

Signature: haveManyBlogsInDatabase(int $count, [array $overrides], [bool $subdomain]) : array

+

Inserts many blogs in the database.

+
<?php
+     $blogIds = $I->haveManyBlogsInDatabase(3, ['domain' =>'test-{{n}}']);
+     foreach($blogIds as $blogId){
+     $I->useBlog($blogId);
+     $I->haveManuPostsInDatabase(3);
+}
+
+

haveManyCommentsInDatabase

+

Signature: haveManyCommentsInDatabase(int $count, int $comment_post_ID, [array $overrides]) : array

+

Inserts many comments in the database.

+
<?php
+// Insert 3 random comments for a post.
+$I->haveManyCommentsInDatabase(3, $postId);
+// Insert 3 random comments for a post.
+$I->haveManyCommentsInDatabase(3, $postId, ['comment_content' => 'Comment {{n}}']);
+
+

haveManyLinksInDatabase

+

Signature: haveManyLinksInDatabase(int $count, [array $overrides]) : array

+

Inserts many links in the database links table.

+
<?php
+// Insert 3 randomly generated links in the database.
+$linkIds = $I->haveManyLinksInDatabase(3);
+// Inserts links in the database replacing the `n` placeholder.
+$linkIds = $I->haveManyLinksInDatabase(3, ['link_url' => 'http://example.org/test-{{n}}']);
+
+

haveManyPostsInDatabase

+

Signature: haveManyPostsInDatabase(int $count, [array $overrides]) : array

+

Inserts many posts in the database returning their IDs.

+
<?php
+// Insert 3 random posts.
+$I->haveManyPostsInDatabase(3);
+// Insert 3 posts with generated titles.
+$I->haveManyPostsInDatabase(3, ['post_title' => 'Test post {{n}}']);
+
+

haveManyTermsInDatabase

+

Signature: haveManyTermsInDatabase(int $count, string $name, string $taxonomy, [array $overrides]) : array

+

Inserts many terms in the database.

+
<?php
+$terms = $I->haveManyTermsInDatabase(3, 'genre-{{n}}', 'genre');
+$termIds = array_column($terms, 0);
+$termTaxonomyIds = array_column($terms, 1);
+
+

haveManyUsersInDatabase

+

Signature: haveManyUsersInDatabase(int $count, string $user_login, [string $role], [array $overrides]) : array

+

Inserts many users in the database.

+
<?php
+$subscribers = $I->haveManyUsersInDatabase(5, 'user-{{n}}');
+$editors = $I->haveManyUsersInDatabase(
+     5,
+     'user-{{n}}',
+     'editor',
+     ['user_email' => 'user-{{n}}@example.org']
+);
+
+

haveMenuInDatabase

+

Signature: haveMenuInDatabase(string $slug, string $location, [array $overrides]) : array

+

Creates and adds a menu to a theme location in the database.

+
<?php
+list($termId, $termTaxId) = $I->haveMenuInDatabase('test', 'sidebar');
+
+

haveMenuItemInDatabase

+

Signature: haveMenuItemInDatabase(string $menuSlug, string $title, [?int $menuOrder], [array $meta]) : int

+

Adds a menu element to a menu for the current theme.

+
<?php
+$I->haveMenuInDatabase('test', 'sidebar');
+$I->haveMenuItemInDatabase('test', 'Test one', 0);
+$I->haveMenuItemInDatabase('test', 'Test two', 1);
+
+

haveOptionInDatabase

+

Signature: haveOptionInDatabase(string $option_name, mixed $option_value, [string $autoload]) : int

+

Inserts an option in the database.

+
<?php
+$I->haveOptionInDatabase('posts_per_page', 23);
+$I->haveOptionInDatabase('my_plugin_options', ['key_one' => 'value_one', 'key_two' => 89]);
+
+

If the option value is an object or an array then the value will be serialized.

+

havePageInDatabase

+

Signature: havePageInDatabase([array $overrides]) : int

+

Inserts a page in the database.

+
<?php
+// Creates a test page in the database with random values.
+$randomPageId = $I->havePageInDatabase();
+// Creates a test page in the database defining its title.
+$testPageId = $I->havePageInDatabase(['post_title' => 'Test page']);
+
+

havePostInDatabase

+

Signature: havePostInDatabase([array $data]) : int

+

Inserts a post in the database.

+
<?php
+// Insert a post with random values in the database.
+$randomPostId = $I->havePostInDatabase();
+// Insert a post with specific values in the database.
+$I->havePostInDatabase([
+'post_type' => 'book',
+'post_title' => 'Alice in Wonderland',
+'meta_input' => [
+'readers_count' => 23
+],
+'tax_input' => [
+['genre' => 'fiction']
+]
+]);
+
+

havePostThumbnailInDatabase

+

Signature: havePostThumbnailInDatabase(int $postId, int $thumbnailId) : int

+

Assigns the specified attachment ID as thumbnail (featured image) to a post.

+
<?php
+$attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));
+$postId = $I->havePostInDatabase();
+$I->havePostThumbnailInDatabase($postId, $attachmentId);
+
+

havePostmetaInDatabase

+

Signature: havePostmetaInDatabase(int $postId, string $meta_key, mixed $meta_value) : int

+

Adds one or more meta key and value couples in the database for a post.

+
<?php
+// Set the post-meta for a post.
+$I->havePostmetaInDatabase($postId, 'karma', 23);
+// Set an array post-meta for a post, it will be serialized in the db.
+$I->havePostmetaInDatabase($postId, 'data', ['one', 'two']);
+// Use a loop to insert one meta per row.
+foreach( ['one', 'two'] as $value){
+     $I->havePostmetaInDatabase($postId, 'data', $value);
+}
+
+

haveSiteMetaInDatabase

+

Signature: haveSiteMetaInDatabase(int $blogId, string $string, mixed $value) : int

+

Adds a meta key and value for a site in the database.

+
<?php
+$I->haveSiteMetaInDatabase(1, 'foo', 'bar');
+$insertedId = $I->haveSiteMetaInDatabase(2, 'foo', ['bar' => 'baz']);
+
+

haveSiteOptionInDatabase

+

Signature: haveSiteOptionInDatabase(string $key, mixed $value) : int

+

Inserts a site option in the database.

+

If the value is an array or an object then the value will be serialized.

+
<?php
+$fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');
+
+

haveSiteTransientInDatabase

+

Signature: haveSiteTransientInDatabase(string $key, mixed $value) : int

+

Inserts a site transient in the database. +If the value is an array or an object then the value will be serialized.

+
<?php
+$I->haveSiteTransientInDatabase('total_comments_count', 23);
+// This value will be serialized.
+$I->haveSiteTransientInDatabase('api_data', ['user' => 'luca', 'token' => '11ae3ijns-j83']);
+
+

haveTermInDatabase

+

Signature: haveTermInDatabase(string $name, string $taxonomy, [array $overrides]) : array

+

Inserts a term in the database.

+
<?php
+// Insert a random 'genre' term in the database.
+$I->haveTermInDatabase('non-fiction', 'genre');
+// Insert a term in the database with term meta.
+$I->haveTermInDatabase('fiction', 'genre', [
+     'slug' => 'genre--fiction',
+     'meta' => [
+        'readers_count' => 23
+     ]
+]);
+
+

haveTermMetaInDatabase

+

Signature: haveTermMetaInDatabase(int $term_id, string $meta_key, mixed $meta_value) : int

+

Inserts a term meta row in the database. +Objects and array meta values will be serialized.

+
<?php
+$I->haveTermMetaInDatabase($fictionId, 'readers_count', 23);
+// Insert some meta that will be serialized.
+$I->haveTermMetaInDatabase($fictionId, 'flags', [3, 4, 89]);
+// Use a loop to insert one meta per row.
+foreach([3, 4, 89] as $value) {
+     $I->haveTermMetaInDatabase($fictionId, 'flag', $value);
+}
+
+

haveTermRelationshipInDatabase

+

Signature: haveTermRelationshipInDatabase(int $object_id, int $term_taxonomy_id, [int $term_order]) : void

+

Creates a term relationship in the database.

+

No check about the consistency of the insertion is made. E.g. a post could be assigned a term from +a taxonomy that's not registered for that post type.

+
<?php
+// Assign the `fiction` term to a book.
+$I->haveTermRelationshipInDatabase($bookId, $fictionId);
+
+

haveTransientInDatabase

+

Signature: haveTransientInDatabase(string $transient, mixed $value) : int

+

Inserts a transient in the database.

+

If the value is an array or an object then the value will be serialized. +Since the transients are set in the context of tests it's not possible to +set an expiration directly.

+
<?php
+// Store an array in the `tweets` transient.
+$I->haveTransientInDatabase('tweets', $tweets);
+
+

haveUserCapabilitiesInDatabase

+

Signature: haveUserCapabilitiesInDatabase(int $userId, array|string $role) : array

+

Sets a user capabilities in the database.

+
<?php
+// Assign one user a role in a blog.
+$blogId = $I->haveBlogInDatabase('test');
+$editor = $I->haveUserInDatabase('luca', 'editor');
+$capsIds = $I->haveUserCapabilitiesInDatabase($editor, [$blogId => 'editor']);
+
+// Assign a user two roles in blog 1.
+$capsIds = $I->haveUserCapabilitiesInDatabase($userId, ['editor', 'subscriber']);
+
+// Assign one user different roles in different blogs.
+$capsIds = $I->haveUserCapabilitiesInDatabase($userId, [$blogId1 => 'editor', $blogId2 => 'author']);
+
+// Assign a user a role and an additional capability in blog 1.
+$I->haveUserCapabilitiesInDatabase($userId, ['editor' => true, 'edit_themes' => true]);
+
+// Assign a user a mix of roles and capabilities in different blogs.
+$capsIds = $I->haveUserCapabilitiesInDatabase(
+     $userId,
+     [
+         $blogId1 => ['editor' => true, 'edit_themes' => true],
+         $blogId2 => ['administrator' => true, 'edit_themes' => false]
+     ]
+);
+
+

haveUserInDatabase

+

Signature: haveUserInDatabase(string $user_login, [array|string $role], [array $overrides]) : int

+

Inserts a user and its meta in the database.

+
<?php
+// Create an editor user in blog 1 w/ specific email.
+$userId = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);
+
+// Create a subscriber user in blog 1.
+$subscriberId = $I->haveUserInDatabase('subscriber');
+
+// Create a user editor in blog 1, author in blog 2, administrator in blog 3.
+$userWithMeta = $I->haveUserInDatabase('luca',
+     [
+         1 => 'editor',
+         2 => 'author',
+         3 => 'administrator'
+     ], [
+         'user_email' => 'luca@example.org'
+         'meta' => ['a meta_key' => 'a_meta_value']
+     ]
+);
+
+// Create editor in blog 1 w/ `edit_themes` cap, author in blog 2, admin in blog 3 w/o `manage_options` cap.
+$userWithMeta = $I->haveUserInDatabase('luca',
+     [
+         1 => ['editor', 'edit_themes'],
+         2 => 'author',
+         3 => ['administrator' => true, 'manage_options' => false]
+     ]
+);
+
+// Create a user w/o role.
+$userId = $I->haveUserInDatabase('luca', '');
+
+

haveUserLevelsInDatabase

+

Signature: haveUserLevelsInDatabase(int $userId, array|string $role) : array

+

Sets the user access level meta in the database for a user.

+
<?php
+$userId = $I->haveUserInDatabase('luca', 'editor');
+$moreThanAnEditorLessThanAnAdmin = 8;
+$I->haveUserLevelsInDatabase($userId, $moreThanAnEditorLessThanAnAdmin);
+
+

haveUserMetaInDatabase

+

Signature: haveUserMetaInDatabase(int $userId, string $meta_key, mixed $meta_value) : array

+

Sets a user meta in the database.

+
<?php
+$userId = $I->haveUserInDatabase('luca', 'editor');
+$I->haveUserMetaInDatabase($userId, 'karma', 23);
+
+

importSql

+

Signature: importSql(array $sql) : void

+

Loads a set SQL code lines in the current database.

+
<?php
+// Import a SQL string.
+$I->importSql([$sqlString]);
+// Import a set of SQL strings.
+$I->importSql($sqlStrings);
+// Import a prepared set of SQL strings.
+$preparedSqlStrings = array_map(function($line){
+    return str_replace('{{date}}', date('Y-m-d H:i:s'), $line);
+}, $sqlTemplate);
+$I->importSql($preparedSqlStrings);
+
+

importSqlDumpFile

+

Signature: importSqlDumpFile([?string $dumpFile]) : void

+

Import the SQL dump file if populate is enabled.

+
<?php
+// Import a dump file passing the absolute path.
+$I->importSqlDumpFile(codecept_data_dir('dumps/start.sql'));
+
+

Specifying a dump file that file will be imported.

+

performInDatabase

+

Signature: performInDatabase($databaseKey, $actions) : void

+

Can be used with a callback if you don't want to change the current database in your test.

+

<?php
+$I->seeNumRecords(2, 'users');   //executed on default database
+$I->performInDatabase('db_books', function($I) {
+    $I->seeNumRecords(30, 'books');  //executed on db_books database
+});
+$I->seeNumRecords(2, 'users');  //executed on default database
+
+List of actions can be pragmatically built using Codeception\Util\ActionSequence:

+

<?php
+$I->performInDatabase('db_books', ActionSequence::build()
+    ->seeNumRecords(30, 'books')
+);
+
+Alternatively an array can be used:

+
<?php
+$I->performInDatabase('db_books', ['seeNumRecords' => [30, 'books']]);
+
+

Choose the syntax you like the most and use it,

+

Actions executed from array or ActionSequence will print debug output for actions, and adds an action name to +exception on failure.

+

seeAttachmentInDatabase

+

Signature: seeAttachmentInDatabase(array $criteria) : void

+

Checks for an attachment in the database.

+
<?php
+$url = 'https://example.org/images/foo.png';
+$I->seeAttachmentInDatabase(['guid' => $url]);
+
+

seeBlogInDatabase

+

Signature: seeBlogInDatabase(array $criteria) : void

+

Checks for a blog in the blogs table.

+
<?php
+// Search for a blog by `blog_id`.
+$I->seeBlogInDatabase(['blog_id' => 23]);
+// Search for all blogs on a path.
+$I->seeBlogInDatabase(['path' => '/sub-path/']);
+
+

seeCommentInDatabase

+

Signature: seeCommentInDatabase(array $criteria) : void

+

Checks for a comment in the database.

+

Will look up the "comments" table.

+
<?php
+$I->seeCommentInDatabase(['comment_ID' => 23]);
+
+

seeCommentMetaInDatabase

+

Signature: seeCommentMetaInDatabase(array $criteria) : void

+

Checks that a comment meta value is in the database. +Will look up the "commentmeta" table.

+
<?php
+// Assert a specified meta for a comment exists.
+$I->seeCommentMetaInDatabase(['comment_ID' => $commentId, 'meta_key' => 'karma', 'meta_value' => 23]);
+// Assert the comment has at least one meta set.
+$I->seeCommentMetaInDatabase(['comment_ID' => $commentId]);
+
+

seeInDatabase

+

Signature: seeInDatabase(string $table, [array $criteria]) : void

+

seeLinkInDatabase

+

Signature: seeLinkInDatabase(array $criteria) : void

+

Checks for a link in the links table of the database.

+
<?php
+// Asserts a link exists by name.
+$I->seeLinkInDatabase(['link_name' => 'my-link']);
+// Asserts at least one link exists for the user.
+$I->seeLinkInDatabase(['link_owner' => $userId]);
+
+

seeNumRecords

+

Signature: seeNumRecords(int $expectedNumber, string $table, [array $criteria]) : void

+

Asserts that the given number of records were found in the database.

+
<?php
+$I->seeNumRecords(1, 'users', ['name' => 'davert'])
+
+

seeOptionInDatabase

+

Signature: seeOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

+

Checks if an option is in the database for the current blog, either by criteria or by name and value.

+

If checking for an array or an object then the serialized version will be checked for.

+
<?php
+// Checks an option is in the database.
+$I->seeOptionInDatabase('tables_version');
+// Checks an option is in the database and has a specific value.
+$I->seeOptionInDatabase('tables_version', '1.0');
+$I->seeOptionInDatabase(['option_name' => 'tables_version', 'option_value' => 1.0']);
+
+

seePageInDatabase

+

Signature: seePageInDatabase(array $criteria) : void

+

Checks for a page in the database.

+
<?php
+// Asserts a page with an exists in the database.
+$I->seePageInDatabase(['ID' => 23]);
+// Asserts a page with a slug and ID exists in the database.
+$I->seePageInDatabase(['post_title' => 'Test Page', 'ID' => 23]);
+
+

seePostInDatabase

+

Signature: seePostInDatabase(array $criteria) : void

+

Checks for a post in the database.

+
<?php
+// Assert a post exists in the database.
+$I->seePostInDatabase(['ID' => 23]);
+// Assert a post with a slug and ID exists in the database.
+$I->seePostInDatabase(['post_content' => 'test content', 'ID' => 23]);
+
+

seePostMetaInDatabase

+

Signature: seePostMetaInDatabase(array $criteria) : void

+

Checks for a post meta value in the database for the current blog.

+

If the meta_value is an object or an array then the check will be made for serialized values.

+
<?php
+$postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']];
+$I->seePostMetaInDatabase(['post_id' => '$postId', 'meta_key' => 'foo']);
+
+

seePostWithTermInDatabase

+

Signature: seePostWithTermInDatabase(int $post_id, int $term_taxonomy_id, [?int $term_order], [?string $taxonomy]) : void

+

Checks that a post to term relation exists in the database.

+

The method will check the "term_relationships" table.

+
<?php
+$fiction = $I->haveTermInDatabase('fiction', 'genre');
+$postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);
+$I->seePostWithTermInDatabase($postId, $fiction['term_taxonomy_id']);
+
+

seeSiteOptionInDatabase

+

Signature: seeSiteOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

+

Checks that a site option is in the database.

+
<?php
+// Check that the option is set in the database.
+$I->seeSiteOptionInDatabase('foo_count');
+// Check that the option is set and has a specific value.
+$I->seeSiteOptionInDatabase('foo_count', 23);
+
+

seeSiteSiteTransientInDatabase

+

Signature: seeSiteSiteTransientInDatabase(string $key, [mixed $value]) : void

+

Checks that a site option is in the database.

+
<?php
+// Check a transient exists.
+$I->seeSiteSiteTransientInDatabase('total_counts');
+// Check a transient exists and has a specific value.
+$I->seeSiteSiteTransientInDatabase('total_counts', 23);
+
+

seeSiteTransientInDatabase

+

Signature: seeSiteTransientInDatabase(string $transient, [mixed $value]) : void

+

Checks that a site transient is in the database.

+
<?php
+$I->haveSiteTransientInDatabase('foo', 23);
+$I->seeSiteTransientInDatabase('foo');
+$I->seeSiteTransientInDatabase('foo', 23);
+
+

seeTableInDatabase

+

Signature: seeTableInDatabase(string $table) : void

+

Checks that a table is in the database.

+
<?php
+$options = $I->grabPrefixedTableNameFor('options');
+$I->seeTableInDatabase($options);
+
+

seeTermInDatabase

+

Signature: seeTermInDatabase(array $criteria) : void

+

Checks for a term in the database. +Looks up the terms and term_taxonomy prefixed tables.

+
<?php
+$I->seeTermInDatabase(['slug' => 'genre--fiction']);
+$I->seeTermInDatabase(['name' => 'Fiction', 'slug' => 'genre--fiction']);
+
+

seeTermMetaInDatabase

+

Signature: seeTermMetaInDatabase(array $criteria) : void

+

Checks for a term meta in the database.

+
<?php
+list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
+$I->haveTermMetaInDatabase($termId, 'rating', 4);
+$I->seeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'rating', 'meta_value' => 4]);
+
+

seeTermRelationshipInDatabase

+

Signature: seeTermRelationshipInDatabase(array $criteria) : void

+

Checks for a term relationship in the database.

+
<?php
+$postId = $I->havePostInDatabase(['tax_input' => ['category' => 'one']]);
+$I->seeTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $oneTermTaxId]);
+
+

seeTermTaxonomyInDatabase

+

Signature: seeTermTaxonomyInDatabase(array $criteria) : void

+

Checks for a taxonomy taxonomy in the database.

+
<?php
+list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
+$I->seeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'genre']);
+
+

seeTransientInDatabase

+

Signature: seeTransientInDatabase(string $name, [mixed $value]) : void

+

Checks that a transient is in the database.

+
<?php
+$I->haveTransientInDatabase('foo', 23);
+$I->seeTransientInDatabase('foo');
+$I->seeTransientInDatabase('foo', 23);
+
+

seeUserInDatabase

+

Signature: seeUserInDatabase(array $criteria) : void

+

Checks that a user is in the database.

+

The method will check the "users" table.

+
<?php
+$I->seeUserInDatabase([
+    "user_email" => "test@example.org",
+    "user_login" => "login name"
+])
+
+

seeUserMetaInDatabase

+

Signature: seeUserMetaInDatabase(array $criteria) : void

+

Checks for a user meta value in the database.

+
<?php
+$I->seeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);
+
+

updateInDatabase

+

Signature: updateInDatabase(string $table, array $data, [array $criteria]) : void

+

Update an SQL record into a database.

+
<?php
+$I->updateInDatabase('users', array('isAdmin' => true), array('email' => 'miles@davis.com'));
+
+

useBlog

+

Signature: useBlog([int $blogId]) : void

+

Sets the blog to be used.

+

This has nothing to do with WordPress switch_to_blog function, this code will affect the table prefixes used.

+

useMainBlog

+

Signature: useMainBlog() : void

+

Sets the current blog to the main one (blog_id 1).

+
<?php
+// Switch to the blog with ID 23.
+$I->useBlog(23);
+// Switch back to the main blog.
+$I->useMainBlog();
+
+

useTheme

+

Signature: useTheme(string $stylesheet, [?string $template], [?string $themeName]) : void

+

Sets the current theme options.

+
<?php
+$I->useTheme('twentyseventeen');
+$I->useTheme('child-of-twentyseventeen', 'twentyseventeen');
+$I->useTheme('acme', 'acme', 'Acme Theme');
+
+ + +

Read more in Codeception documentation for the Db module.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/WPFilesystem/index.html b/modules/WPFilesystem/index.html new file mode 100644 index 000000000..909de11b1 --- /dev/null +++ b/modules/WPFilesystem/index.html @@ -0,0 +1,4756 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPFilesystem - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

WPFilesystem

+ +

WPFilesystem module

+

Interact and make assertions on the WordPress file structure.

+

This module is used together with the WPDb module to manage the state of the WordPress installation in the +context of end-to-end tests.

+

This module extends the Filesystem module from Codeception, you can reference to the Codeception documentation to +find out more about the module configuration and usage.

+

This module should be with Cest and Cept test cases.

+

Configuration

+

wpRootFolder - required; the path to the WordPress installation root folder. This can be a relative path to the +codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation +directory is the directory that contains the wp-load.php file. +themes - the path, relative to the path specified in the wpRootFolder parameter, to the themes directory. By +default, +it's /wp-content/themes. +plugins - the path, relative to the path specified in the wpRootFolder parameter, to the plugins directory. By +default, it's /wp-content/plugins. +mu-plugins - the path, relative to the path specified in the wpRootFolder parameter, to the must-use plugins. By +default, it's /wp-content/mu-plugins. directory. +uploads - the path, relative to the path specified in the wpRootFolder parameter, to the uploads directory. By +default, it's /wp-content/uploads.

+

The following is an example of the module configuration to run tests on the /var/wordpress site:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPFilesystem:
+      wpRootFolder: /var/wordpress
+      themes: wp-content/themes
+      plugins: wp-content/plugins
+      mu-plugins: wp-content/mu-plugins
+      uploads: wp-content/uploads
+
+

The following configuration uses dynamic configuration parameters to set the module configuration:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPFilesystem:
+      wpRootFolder: '%WP_ROOT_FOLDER%'
+
+

Methods

+

The module provides the following methods:

+ + +

amInMuPluginPath

+

Signature: amInMuPluginPath(string $path) : void

+

Sets the current working folder to a folder in a mu-plugin.

+
$I->amInMuPluginPath('mu-plugin');
+
+

amInPath

+

Signature: amInPath(string $path) : void

+

Enters a directory In local filesystem. +Project root directory is used by default

+

amInPluginPath

+

Signature: amInPluginPath(string $path) : void

+

Sets the current working folder to a folder in a plugin.

+
$I->amInPluginPath('my-plugin');
+
+

amInThemePath

+

Signature: amInThemePath(string $path) : void

+

Sets the current working folder to a folder in a theme.

+
$I->amInThemePath('my-theme');
+
+

amInUploadsPath

+

Signature: amInUploadsPath([?string $path]) : void

+

Enters, changing directory, to the uploads folder in the local filesystem.

+
<?php
+$I->amInUploadsPath('/logs');
+$I->seeFileFound('shop.log');
+
+

assertDirectoryExists

+

Signature: assertDirectoryExists(string $directory, [string $message]) : void

+

cleanDir

+

Signature: cleanDir(string $dirname) : void

+

Erases directory contents

+
<?php
+$I->cleanDir('logs');
+
+

cleanMuPluginDir

+

Signature: cleanMuPluginDir(string $dir) : void

+

Cleans, emptying it, a folder in a mu-plugin folder.

+
$I->cleanMuPluginDir('mu-plugin1/foo');
+
+

cleanPluginDir

+

Signature: cleanPluginDir(string $dir) : void

+

Cleans, emptying it, a folder in a plugin folder.

+
$I->cleanPluginDir('my-plugin/foo');
+
+

cleanThemeDir

+

Signature: cleanThemeDir(string $dir) : void

+

Clears, emptying it, a folder in a theme folder.

+
$I->cleanThemeDir('my-theme/foo');
+
+

cleanUploadsDir

+

Signature: cleanUploadsDir([?string $dir], [DateTime|string|int|null $date]) : void

+

Clears a folder in the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
$I->cleanUploadsDir('some/folder');
+$I->cleanUploadsDir('some/folder', 'today');
+
+

copyDir

+

Signature: copyDir(string $src, string $dst) : void

+

Copies directory with all contents

+
<?php
+$I->copyDir('vendor','old_vendor');
+
+

copyDirToMuPlugin

+

Signature: copyDirToMuPlugin(string $src, string $pluginDst) : void

+

Copies a folder to a folder in a mu-plugin.

+
$I->copyDirToMuPlugin(codecept_data_dir('foo'), 'mu-plugin/foo');
+
+

copyDirToPlugin

+

Signature: copyDirToPlugin(string $src, string $pluginDst) : void

+

Copies a folder to a folder in a plugin.

+
// Copy the 'foo' folder to the 'foo' folder in the plugin.
+$I->copyDirToPlugin(codecept_data_dir('foo'), 'my-plugin/foo');
+
+

copyDirToTheme

+

Signature: copyDirToTheme(string $src, string $themeDst) : void

+

Copies a folder in a theme folder.

+
$I->copyDirToTheme(codecept_data_dir('foo'), 'my-theme');
+
+

copyDirToUploads

+

Signature: copyDirToUploads(string $src, string $dst, [DateTime|string|int|null $date]) : void

+

Copies a folder to the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
$I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo');
+$I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo', 'today');
+
+

deleteDir

+

Signature: deleteDir(string $dirname) : void

+

Deletes directory with all subdirectories

+
<?php
+$I->deleteDir('vendor');
+
+

deleteFile

+

Signature: deleteFile(string $filename) : void

+

Deletes a file

+
<?php
+$I->deleteFile('composer.lock');
+
+

deleteMuPluginFile

+

Signature: deleteMuPluginFile(string $file) : void

+

Deletes a file in a mu-plugin folder.

+
$I->deleteMuPluginFile('mu-plugin1/some-file.txt');
+
+

deletePluginFile

+

Signature: deletePluginFile(string $file) : void

+

Deletes a file in a plugin folder.

+
$I->deletePluginFile('my-plugin/some-file.txt');
+
+

deleteThemeFile

+

Signature: deleteThemeFile(string $file) : void

+

Deletes a file in a theme folder.

+
$I->deleteThemeFile('my-theme/some-file.txt');
+
+

deleteThisFile

+

Signature: deleteThisFile() : void

+

Deletes a file

+

deleteUploadedDir

+

Signature: deleteUploadedDir(string $dir, [DateTime|string|int|null $date]) : void

+

Deletes a dir in the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
$I->deleteUploadedDir('folder');
+$I->deleteUploadedDir('folder', 'today');
+
+

deleteUploadedFile

+

Signature: deleteUploadedFile(string $file, [string|int|null $date]) : void

+

Deletes a file in the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
$I->deleteUploadedFile('some-file.txt');
+$I->deleteUploadedFile('some-file.txt', 'today');
+
+

dontSeeFileFound

+

Signature: dontSeeFileFound(string $filename, [string $path]) : void

+

Checks if file does not exist in path

+

dontSeeInMuPluginFile

+

Signature: dontSeeInMuPluginFile(string $file, string $contents) : void

+

Checks that a file in a mu-plugin folder does not contain a string.

+
$I->dontSeeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');
+
+

dontSeeInPluginFile

+

Signature: dontSeeInPluginFile(string $file, string $contents) : void

+

Checks that a file in a plugin folder does not contain a string.

+
$I->dontSeeInPluginFile('my-plugin/some-file.txt', 'foo');
+
+

dontSeeInThemeFile

+

Signature: dontSeeInThemeFile(string $file, string $contents) : void

+

Checks that a file in a theme folder does not contain a string.

+
$I->dontSeeInThemeFile('my-theme/some-file.txt', 'foo');
+
+

dontSeeInThisFile

+

Signature: dontSeeInThisFile(string $text) : void

+

Checks If opened file doesn't contain text in it

+
<?php
+$I->openFile('composer.json');
+$I->dontSeeInThisFile('codeception/codeception');
+
+

dontSeeInUploadedFile

+

Signature: dontSeeInUploadedFile(string $file, string $contents, [string|int|null $date]) : void

+

Checks that a file in the uploads folder does contain a string.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
<?php
+$I->dontSeeInUploadedFile('some-file.txt', 'foo');
+$I->dontSeeInUploadedFile('some-file.txt','foo', 'today');
+
+

dontSeeMuPluginFileFound

+

Signature: dontSeeMuPluginFileFound(string $file) : void

+

Checks that a file is not found in a mu-plugin folder.

+
$I->dontSeeMuPluginFileFound('mu-plugin1/some-file.txt');
+
+

dontSeePluginFileFound

+

Signature: dontSeePluginFileFound(string $file) : void

+

Checks that a file is not found in a plugin folder.

+
$I->dontSeePluginFileFound('my-plugin/some-file.txt');
+
+

dontSeeThemeFileFound

+

Signature: dontSeeThemeFileFound(string $file) : void

+

Checks that a file is not found in a theme folder.

+
$I->dontSeeThemeFileFound('my-theme/some-file.txt');
+
+

dontSeeUploadedFileFound

+

Signature: dontSeeUploadedFileFound(string $file, [string|int|null $date]) : void

+

Checks thata a file does not exist in the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
$I->dontSeeUploadedFileFound('some-file.txt');
+$I->dontSeeUploadedFileFound('some-file.txt','today');
+
+

getBlogUploadsPath

+

Signature: getBlogUploadsPath(int $blogId, [string $file], [DateTimeImmutable|DateTime|string|null $date]) : string

+

Returns the absolute path to a blog uploads folder or file.

+
<?php
+$blogId = $I->haveBlogInDatabase('test');
+$testTodayUploads = $I->getBlogUploadsPath($blogId);
+$testLastMonthLogs = $I->getBlogUploadsPath($blogId, '/logs', '-1 month');
+
+

getUploadsPath

+

Signature: getUploadsPath([string $file], [mixed $date]) : string

+

Returns the path to the specified uploads file of folder.

+

Not providing a value for $file and $date will return the uploads folder path.

+
<?php
+$todaysPath = $I->getUploadsPath();
+$lastWeek = $I->getUploadsPath('', '-1 week');
+
+

getWpRootFolder

+

Signature: getWpRootFolder() : string

+

Returns the absolute path to WordPress root folder without trailing slash.

+
<?php
+$rootFolder = $I->getWpRootFolder();
+$I->assertFileExists($rootFolder . 'wp-load.php');
+
+

haveMuPlugin

+

Signature: haveMuPlugin(string $filename, string $code) : void

+

Creates a mu-plugin file, including plugin header, in the mu-plugins folder.

+

The code can not contain the opening '<?php' tag.

+
$code = 'echo "Hello world!"';
+$I->haveMuPlugin('foo-mu-plugin.php', $code);
+// Load the code from a file.
+$code = file_get_contents(codecept_data_dir('code/mu-plugin.php'));
+$I->haveMuPlugin('foo-mu-plugin.php', $code);
+
+

havePlugin

+

Signature: havePlugin(string $path, string $code) : void

+

Creates a plugin file, including plugin header, in the plugins folder.

+

The plugin is just created and not activated; the code can not contain the opening '<?php' tag.

+
$code = 'echo "Hello world!"';
+$I->havePlugin('foo/plugin.php', $code);
+// Load the code from a file.
+$code = file_get_contents(codecept_data_dir('code/plugin.php'));
+$I->havePlugin('foo/plugin.php', $code);
+
+

haveTheme

+

Signature: haveTheme(string $folder, string $indexFileCode, [string $functionsFileCode]) : void

+

Creates a theme file structure, including theme style file and index, in the themes folder.

+

The theme is just created and not activated; the code can not contain the opening '<?php' tag.

+
$code = 'sayHi();';
+$functionsCode  = 'function sayHi(){echo "Hello world";};';
+$I->haveTheme('foo', $indexCode, $functionsCode);
+// Load the code from a file.
+$indexCode = file_get_contents(codecept_data_dir('code/index.php'));
+$functionsCode = file_get_contents(codecept_data_dir('code/functions.php'));
+$I->haveTheme('foo', $indexCode, $functionsCode);
+
+

makeUploadsDir

+

Signature: makeUploadsDir(string $path) : string

+

Creates an empty folder in the WordPress installation uploads folder.

+
<?php
+$logsDir = $I->makeUploadsDir('logs/acme');
+
+

openFile

+

Signature: openFile(string $filename) : void

+

Opens a file and stores it's content.

+

Usage:

+
<?php
+$I->openFile('composer.json');
+$I->seeInThisFile('codeception/codeception');
+
+

openUploadedFile

+

Signature: openUploadedFile(string $filename, [DateTime|string|int|null $date]) : void

+

Opens a file in the the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
$I->openUploadedFile('some-file.txt');
+$I->openUploadedFile('some-file.txt', 'time');
+
+

seeFileContentsEqual

+

Signature: seeFileContentsEqual(string $text) : void

+

Checks the strict matching of file contents. +Unlike seeInThisFile will fail if file has something more than expected lines. +Better to use with HEREDOC strings. +Matching is done after removing "\r" chars from file content.

+
<?php
+$I->openFile('process.pid');
+$I->seeFileContentsEqual('3192');
+
+

seeFileFound

+

Signature: seeFileFound(string $filename, [string $path]) : void

+

Checks if file exists in path. +Opens a file when it's exists

+
<?php
+$I->seeFileFound('UserModel.php','app/models');
+
+

seeInMuPluginFile

+

Signature: seeInMuPluginFile(string $file, string $contents) : void

+

Checks that a file in a mu-plugin folder contains a string.

+
$I->seeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');
+
+

seeInPluginFile

+

Signature: seeInPluginFile(string $file, string $contents) : void

+

Checks that a file in a plugin folder contains a string.

+
$I->seeInPluginFile('my-plugin/some-file.txt', 'foo');
+
+

seeInThemeFile

+

Signature: seeInThemeFile(string $file, string $contents) : void

+

Checks that a file in a theme folder contains a string.

+
<?php
+$I->seeInThemeFile('my-theme/some-file.txt', 'foo');
+?>
+
+

seeInThisFile

+

Signature: seeInThisFile(string $text) : void

+

Checks If opened file has text in it.

+

Usage:

+
<?php
+$I->openFile('composer.json');
+$I->seeInThisFile('codeception/codeception');
+
+

seeInUploadedFile

+

Signature: seeInUploadedFile(string $file, string $contents, [string|int|null $date]) : void

+

Checks that a file in the uploads folder contains a string.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
<?php
+$I->seeInUploadedFile('some-file.txt', 'foo');
+$I->seeInUploadedFile('some-file.txt','foo', 'today');
+
+

seeMuPluginFileFound

+

Signature: seeMuPluginFileFound(string $file) : void

+

Checks that a file is found in a mu-plugin folder.

+
$I->seeMuPluginFileFound('mu-plugin1/some-file.txt');
+
+

seeNumberNewLines

+

Signature: seeNumberNewLines(int $number) : void

+

Checks If opened file has the number of new lines.

+

Usage:

+
<?php
+$I->openFile('composer.json');
+$I->seeNumberNewLines(5);
+
+

seePluginFileFound

+

Signature: seePluginFileFound(string $file) : void

+

Checks that a file is found in a plugin folder.

+
$I->seePluginFileFound('my-plugin/some-file.txt');
+
+

seeThemeFileFound

+

Signature: seeThemeFileFound(string $file) : void

+

Checks that a file is found in a theme folder.

+
$I->seeThemeFileFound('my-theme/some-file.txt');
+
+

seeThisFileMatches

+

Signature: seeThisFileMatches(string $regex) : void

+

Checks that contents of currently opened file matches $regex

+

seeUploadedFileFound

+

Signature: seeUploadedFileFound(string $filename, [string|int|null $date]) : void

+

Checks if file exists in the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
<?php
+$I->seeUploadedFileFound('some-file.txt');
+$I->seeUploadedFileFound('some-file.txt','today');
+?>
+
+

writeToFile

+

Signature: writeToFile(string $filename, string $contents) : void

+

Saves contents to file

+

writeToMuPluginFile

+

Signature: writeToMuPluginFile(string $file, string $data) : void

+

Writes a file in a mu-plugin folder.

+
$I->writeToMuPluginFile('mu-plugin1/some-file.txt', 'foo');
+
+

writeToPluginFile

+

Signature: writeToPluginFile(string $file, string $data) : void

+

Writes a file in a plugin folder.

+
$I->writeToPluginFile('my-plugin/some-file.txt', 'foo');
+
+

writeToThemeFile

+

Signature: writeToThemeFile(string $file, string $data) : void

+

Writes a string to a file in a theme folder.

+
$I->writeToThemeFile('my-theme/some-file.txt', 'foo');
+
+

writeToUploadedFile

+

Signature: writeToUploadedFile(string $filename, string $data, [DateTime|string|int|null $date]) : string

+

Writes a string to a file in the the uploads folder.

+

The date argument can be a string compatible with strtotime or a Unix +timestamp that will be used to build the Y/m uploads subfolder path.

+
$I->writeToUploadedFile('some-file.txt', 'foo bar');
+$I->writeToUploadedFile('some-file.txt', 'foo bar', 'today');
+
+ + +

Read more in Codeception documentation.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/WPLoader/index.html b/modules/WPLoader/index.html new file mode 100644 index 000000000..2128cde11 --- /dev/null +++ b/modules/WPLoader/index.html @@ -0,0 +1,3513 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPLoader - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + + + +

WPLoader

+ +

WPLoader module

+

A module to load WordPress and make its code available in tests.

+

Depending on the value of the loadOnly configuration parameter, the module will behave differently:

+
    +
  • loadOnly: false - The module will load WordPress like the Core PHPUnit suite does to run integration tests in a + controlled environment. Use the module in this mode with test cases generated + using the generate:wpunit command.
  • +
  • loadOnly: true - The module will load WordPress to make it available in the context of tests. Use the module in this + mode in Cest, Cept and Codeception unit test cases.
  • +
+

Configuration with loadOnly: false

+

The module will load WordPress like the Core PHPUnit suite does to run integration tests in a controlled +environment.
+Together with the test case generated by the generate:wpunit command the module +will:

+
    +
  • take care of running any test method in a database transaction rolled back after each test
  • +
  • manage and clean up the global environment and context between tests
  • +
+

When used in this mode, the module supports the following configuration parameters:

+
    +
  • loadOnly - false to load WordPress and run tests in a controlled environment.
  • +
  • wpRootFolder - required; the path to the WordPress installation root folder. This can be a relative path to the + codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation + directory is the directory that contains the wp-load.php file.
  • +
  • dbUrl - required; the URL to the database to use to run tests. The URL must be in the form + mysql://username:password@host:port/database to use a MySQL database, or in the form sqlite://path/to/database to + use a SQLite database. Alternatively, you can use the dbName, dbUser, dbPassword, dbHost configuration + parameters to specify the database connection details.
  • +
  • dump - the path to a database dump, or a set of database dumps, to load before running tests. The dump will be + loaded only once, after the tests run.
  • +
  • tablePrefix - the database table prefix to use when loading WordPress, defaults to wp_.
  • +
  • multisite - a boolean value to indicate if WordPress should be loaded and initialized in multisite mode.
  • +
  • dbCharset - the database charset to use when loading WordPress.
  • +
  • dbCollate - the database collate to use when loading WordPress.
  • +
  • domain - the domain to use when loading WordPress. Equivalent to defining the WP_TESTS_DOMAIN constant.
  • +
  • adminEmail - the administrator email to use when loading WordPress. Equivalent to defining the WP_TESTS_EMAIL + constant.
  • +
  • title - the site title to use when loading WordPress. Equivalent to defining the WP_TESTS_TITLE constant.
  • +
  • phpBinary - the path to the PHP binary to use to run tests. Defaults to the WP_PHP_BINARY constant.
  • +
  • language - the language to use when loading WordPress. Equivalent to defining the WPLANG constant.
  • +
  • configFile - a configuration file, or a set of configuration files, to load before the tests to further customize + and control the WordPress testing environment.
  • +
  • pluginsFolder - the path to the plugins folder to use when loading WordPress. Equivalent to defining the + WP_PLUGIN_DIR constant.
  • +
  • plugins - a list of plugins to activate and load in the WordPress installation. If the plugin is located in the + WordPress installation plugins directory, then the plugin name can be specified using the directory/file.php format. + If the plugin is located in an arbitrary path inside or outiside of the WordPress installation or project, then the + plugin name must be specified either as an absolute path or as a relative path to the project root folder.
  • +
  • silentlyActivatePlugins - a list of plugins to activate silently, without firing their activation hooks. + Depending on the plugin, a silent activation might cause the plugin to not work correctly. The list must be in the + same format as the plugins parameter and plugin should be activated silently only if they are not working correctly + during normal activation and are known to work correctly when activated silently. Plugin paths can be specified + following the same format of the plugins parameter.
  • +
  • bootstrapActions - a list of actions or callables to call after WordPress is loaded and before the tests run.
  • +
  • theme - the theme to activate and load in the WordPress installation. The theme can be specified in slug format, + e.g., twentytwentythree, to load it from the WordPress installation themes directory. Alternatively, the theme can + be specified as an absolute or relative path to a theme folder, e.g., /home/themes/my-theme or vendor/acme/vendor-theme. To use both a parent and ha child theme from arbitrary absolute or relative paths, define the theme parameter as an array of theme paths, e.g., ['/home/themes/parent-theme', '.'].
  • +
  • AUTH_KEY - the AUTH_KEY constant value to use when loading WordPress. If the wpRootFolder path points at a + configured installation, containing the wp-config.php file, then the value of the constant in the configuration file + will be used, else it will be randomly generated.
  • +
  • SECURE_AUTH_KEY - the SECURE_AUTH_KEY constant value to use when loading WordPress. If the wpRootFolder path + points at a configured installation, containing the wp-config.php file, then the value of the constant in the + configuration file will be used, else it will be randomly generated.
  • +
  • LOGGED_IN_KEY - the LOGGED_IN_KEY constant value to use when loading WordPress. If the wpRootFolder path points + at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration + file will be used, else it will be randomly generated.
  • +
  • NONCE_KEY - the NONCE_KEY constant value to use when loading WordPress. If the wpRootFolder path points at a + configured installation, containing the wp-config.php file, then the value of the constant in the configuration file + will be used, else it will be randomly generated.
  • +
  • AUTH_SALT - the AUTH_SALT constant value to use when loading WordPress. If the wpRootFolder path points at a + configured installation, containing the wp-config.php file, then the value of the constant in the configuration file + will be used, else it will be randomly generated.
  • +
  • SECURE_AUTH_SALT - the SECURE_AUTH_SALT constant value to use when loading WordPress. If the wpRootFolder path + points at a configured installation, containing the wp-config.php file, then the value of the constant in the + configuration file will be used, else it will be randomly generated.
  • +
  • LOGGED_IN_SALT - the LOGGED_IN_SALT constant value to use when loading WordPress. If the wpRootFolder path + points at a configured installation, containing the wp-config.php file, then the value of the constant in the + configuration file will be used, else it will be randomly generated.
  • +
  • NONCE_SALT - the NONCE_SALT constant value to use when loading WordPress. If the wpRootFolder path points at a + configured installation, containing the wp-config.php file, then the value of the constant in the configuration file + will be used, else it will be randomly generated.
  • +
  • AUTOMATIC_UPDATER_DISABLED - the AUTOMATIC_UPDATER_DISABLED constant value to use when loading WordPress. If + the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of + the constant in the configuration file will be used, else it will be randomly generated.
  • +
  • WP_HTTP_BLOCK_EXTERNAL - the WP_HTTP_BLOCK_EXTERNAL constant value to use when loading WordPress. If + the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of + the constant in the configuration file will be used, else it will be randomly generated.
  • +
  • backupGlobals - a boolean value to indicate if the global environment should be backed up before each test. Defaults + to true. The globals' backup involves serialization of the global state, plugins or themes that define classes + developed to prevent serialization of the global state will cause the tests to fail. Set this parameter to false to + disable the global environment backup, or use a more refined approach setting the backupGlobalsExcludeList parameter + below. Note that a test case that is explicitly setting the backupGlobals property will override this configuration + parameter.
  • +
  • backupGlobalsExcludeList - a list of global variables to exclude from the global environment backup. The list must + be in the form of array, and it will be merged to the list of globals excluded by default.
  • +
  • backupStaticAttributes - a boolean value to indicate if static attributes of classes should be backed up before each + test. Defaults to true. The static attributes' backup involves serialization of the global state, plugins or themes + that define classes developed to prevent serialization of the global state will cause the tests to fail. Set this + parameter to false to disable the static attributes backup, or use a more refined approanch setting + the backupStaticAttributesExcludeList parameter below. Note that a test case that is explicitly setting + the backupStaticAttributes property will override this configuration parameter.
  • +
  • backupStaticAttributesExcludeList - a list of classes to exclude from the static attributes backup. The list must be + in the form of map from class names to the array of method names to exclude from the backup. See an example below.
  • +
  • skipInstall - a boolean value to indicate if the WordPress installation should be skipped between runs, when already + installed. Defaults to false. During boot, the WPLoader module will re-install WordPress and activate, on top of + the fresh installation, any plugin and theme specified in the plugins and theme configuration parameters: this can + be a time-consuming operation. Set this parameter to true to run the WordPress installation once and just load it on + the following runs. To force the installation to run again, rerun the suite using the WPLoader module using + the --debug flag or delete the _wploader-state.sql file in the suite directory. This configuration parameter is + ignored when the loadOnly parameter is set to true.
  • +
  • beStrictAboutWpdbConnectionId - a boolean value to indicate if the WPTestCase class should throw an exception if + the database connection is closed during any setUpBeforeClass method; default is true.
  • +
+

This is an example of an integration suite configured to use the module:

+
actor: IntegrationTester
+bootstrap: _bootstrap.php
+modules:
+  enabled:
+    - \Helper\Integration
+    - lucatume\WPBrowser\Module\WPLoader:
+        wpRootFolder: /var/wordpress
+        dbUrl: mysql://root:root@mysql:3306/wordpress
+        tablePrefix: test_
+        domain: wordpress.test
+        adminEmail: admin@wordpress.test
+        title: 'Integration Tests'
+        plugins:
+          # This plugin will be loaded from the WordPress installation plugins directory.
+          - hello.php 
+          # This plugin will be loaded from an arbitrary absolute path.
+          - /home/plugins/woocommerce/woocommerce.php 
+          # This plugin will be loaded from an arbitrary relative path inside the project root folder.
+          - vendor/acme/project/plugin.php
+          # This plugin will be loaded from the project root folder.
+          - my-plugin.php
+        theme: twentytwentythree # Load the theme from the WordPress installation themes directory.
+
+

The following configuration uses dynamic configuration parameters to set the module configuration:

+
actor: IntegrationTester
+bootstrap: _bootstrap.php
+modules:
+  enabled:
+    - \Helper\Integration
+    - lucatume\WPBrowser\Module\WPLoader:
+        wpRootFolder: '%WP_ROOT_FOLDER%'
+        dbUrl: '%WP_DB_URL%'
+        tablePrefix: '%WP_TABLE_PREFIX%'
+        domain: '%WP_DOMAIN%'
+        adminEmail: '%WP_ADMIN_EMAIL%'
+        title: '%WP_TITLE%'
+        plugins:
+          - hello.php
+          - /home/plugins/woocommerce/woocommerce.php
+          - my-plugin.php
+          - vendor/acme/project/plugin.php
+        # Parent theme from the WordPress installation themes directory, child theme from absolute path.
+        theme: [twentytwentythree, /home/themes/my-theme]
+
+

The following example configuration uses a SQLite database and loads a database fixture before the tests run:

+
actor: IntegrationTester
+bootstrap: _bootstrap.php
+modules:
+  enabled:
+    - \Helper\Integration
+    - lucatume\WPBrowser\Module\WPLoader:
+        wpRootFolder: /var/wordpress
+        dbUrl: sqlite:///var/wordpress/wp-tests.sqlite
+        dump:
+          - tests/_data/products.sql
+          - tests/_data/users.sql
+          - tests/_data/orders.sql
+        tablePrefix: test_
+        domain: wordpress.test
+        adminEmail: admin@wordpress.test
+        title: 'Integration Tests'
+        plugins:
+          - hello.php
+          - woocommerce/woocommerce.php
+          - my-plugin/my-plugin.php
+        theme: 
+          # Parent theme from relative path.
+          - vendor/acme/parent-theme
+          # Child theme from the current working directory.
+          - .
+
+

The follow example configuration prevents the backup of globals and static attributes in all the tests of the suite that +are not explicitly overriding the backupGlobals and backupStaticAttributes properties:

+
actor: IntegrationTester
+bootstrap: _bootstrap.php
+modules:
+  enabled:
+    - \Helper\Integration
+    - lucatume\WPBrowser\Module\WPLoader:
+        wpRootFolder: /var/wordpress
+        dbUrl: sqlite:///var/wordpress/wp-tests.sqlite
+        dump:
+          - tests/_data/products.sql
+          - tests/_data/users.sql
+          - tests/_data/orders.sql
+        tablePrefix: test_
+        domain: wordpress.test
+        adminEmail: admin@wordpress.test
+        title: 'Integration Tests'
+        plugins:
+          - hello.php
+          - woocommerce/woocommerce.php
+          - my-plugin/my-plugin.php
+        theme: twentytwentythree
+        backupGlobals: false
+        backupStaticAttributes: false 
+
+

The following configuration prevents the backup of some globals and static attributes:

+
actor: IntegrationTester
+bootstrap: _bootstrap.php
+modules:
+  enabled:
+    - \Helper\Integration
+    - lucatume\WPBrowser\Module\WPLoader:
+        wpRootFolder: /var/wordpress
+        dbUrl: sqlite:///var/wordpress/wp-tests.sqlite
+        dump:
+          - tests/_data/products.sql
+          - tests/_data/users.sql
+          - tests/_data/orders.sql
+        tablePrefix: test_
+        domain: wordpress.test
+        adminEmail: admin@wordpress.test
+        title: 'Integration Tests'
+        plugins:
+          - hello.php
+          - woocommerce/woocommerce.php
+          - my-plugin/my-plugin.php
+        theme: twentytwentythree
+        backupGlobalsExcludeList:
+          - my_plugin_will_explode_on_wakeup
+          - another_problematic_global
+        backupStaticAttributesExcludeList:
+          - MyPlugin\MyClass:
+              - instance
+              - anotherStaticAttributeThatWillExplodeOnWakeup
+          - AnotherPlugin\AnotherClass:
+              - instance
+              - yetAnotherStaticAttributeThatWillExplodeOnWakeup
+
+

Handling a custom site structure

+

The setup process should just work for standard and non-standard WordPress installations alike.

+

Even if you're working on a site project using a custom file structure, e.g. Bedrock, you will be able to set up +your site to run tests using the default configuration based on PHP built-in server, Chromedriver and SQLite database.

+

Configuration with loadOnly: true

+

The module will load WordPress from the location specified by the wpRootFodler parameter, relying +on the WPDb module to manage the database state.

+

When used in this mode, the module supports the following configuration parameters:

+
    +
  • loadOnly - true to load WordPress and make it available in the context of tests.
  • +
  • wpRootFolder - required; the path to the WordPress installation root folder. This can be a relative path to the + codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation + directory is the directory that contains the wp-load.php file.
  • +
  • dbUrl - required; the URL to the database to use to run tests. The URL must be in the form + mysql://username:password@host:port/database to use a MySQL database, or in the form sqlite://path/to/database to + use a SQLite database. Alternatively, you can use the dbName, dbUser, dbPassword, dbHost configuration + parameters to specify the database connection details.
  • +
  • domain - the domain to use when loading WordPress. Equivalent to defining the WP_TESTS_DOMAIN constant.
  • +
+

The following is an example of the module configuration to run end-to-end tests on the site served +at http://localhost:8080 URL and served from the /var/wordpress directory:

+
actor: EndToEndTester
+bootstrap: _bootstrap.php
+modules:
+  enabled:
+    - \Helper\Integration
+    - lucatume\WPBrowser\Module\WPWebDriver:
+        url: 'http://localhost:8080'
+        adminUsername: 'admin'
+        adminPassword: 'password'
+        adminPath: '/wp-admin'
+        browser: chrome
+        host: 'localhost'
+        port: '4444'
+        path: '/'
+        window_size: false
+        capabilities:
+          "goog:chromeOptions":
+            args:
+              - "--headless"
+              - "--disable-gpu"
+              - "--disable-dev-shm-usage"
+              - "--proxy-server='direct://'"
+              - "--proxy-bypass-list=*"
+              - "--no-sandbox"
+    - lucatume\WPBrowser\Module\WPDb:
+        dbUrl: 'mysql://root:password@localhost:3306/wordpress'
+        url: 'http://localhost:8080'
+        tablePrefix: 'wp_'
+        dump: 'tests/_data/dump.sql'
+        populate: true
+        cleanup: true
+        reconnect: false
+        urlReplacement: true
+        originalUrl: http://wordpress.test
+        waitlock: 10
+        createIfNotExists: true
+    - lucatume\WPBrowser\Module\WPLoader:
+        loadOnly: true
+        wpRootFolder: /var/wordpress
+        dbUrl: 'mysql://root:password@localhost:3306/wordpress'
+        domain: wordpress.test
+
+

Methods

+

The module provides the following methods:

+ + +

factory

+

Signature: factory() : lucatume\WPBrowser\Module\WPLoader\FactoryStore

+

Accessor method to get the object storing the factories for things. +This method gives access to the same factories provided by the +Core test suite.

+

getContentFolder

+

Signature: getContentFolder([string $path]) : string

+

Returns the absolute path to the WordPress content directory.

+

getInstallation

+

Signature: getInstallation() : lucatume\WPBrowser\WordPress\Installation

+

getPluginsFolder

+

Signature: getPluginsFolder([string $path]) : string

+

Returns the absolute path to the plugins directory.

+

The value will first look at the WP_PLUGIN_DIR constant, then the pluginsFolder configuration parameter +and will, finally, look in the default path from the WordPress root directory.

+

getThemesFolder

+

Signature: getThemesFolder([string $path]) : string

+

Returns the absolute path to the themes directory.

+

getWpRootFolder

+

Signature: getWpRootFolder([?string $path]) : string

+

Returns the absolute path to the WordPress root folder or a path within it..

+ + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/WPQueries/index.html b/modules/WPQueries/index.html new file mode 100644 index 000000000..21b37f6fb --- /dev/null +++ b/modules/WPQueries/index.html @@ -0,0 +1,4077 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPQueries - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

WPQueries

+ +

WPQueries module

+

This module provides assertions for WordPress queries.

+

This module can be used in any test context where the global $wpdb variable is defined, this usually means in any +suite where the WPLoader module is used.

+

Configuration

+

The method does not require configuration.

+

Methods

+

The module provides the following methods:

+ + +

assertCountQueries

+

Signature: assertCountQueries(int $n, [string $message]) : void

+

Asserts that n queries have been made.

+
<?php
+$posts = $this->factory()->post->create_many(3);
+$cachedUsers = $this->factory()->user->create_many(2);
+$nonCachedUsers = $this->factory()->user->create_many(2);
+foreach($cachedUsers as $userId){
+     wp_cache_set('page-posts-for-user-' . $userId, $posts, 'acme');
+}
+// Run the same query as different users
+foreach(array_merge($cachedUsers, $nonCachedUsers) as $userId){
+     $pagePosts = $plugin->getPagePostsForUser($userId);
+}
+$I->assertCountQueries(2, 'A query should be made for each user missing cached posts.')
+
+

assertNotQueries

+

Signature: assertNotQueries([string $message]) : void

+

Asserts that no queries were made.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$posts = $this->factory()->post->create_many(3);
+wp_cache_set('page-posts', $posts, 'acme');
+$pagePosts = $plugin->getPagePosts();
+$I->assertNotQueries('Queries should not be made if the cache is set.')
+
+

assertNotQueriesByAction

+

Signature: assertNotQueriesByAction(string $action, [string $message]) : void

+

Asserts that no queries were made as a consequence of the specified action.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_action( 'edit_post', function($postId){
+        $count = get_option('acme_title_updates_count');
+        update_option('acme_title_updates_count', ++$count);
+} );
+wp_delete_post($bookId);
+$this->assertNotQueriesByAction('edit_post');
+
+

assertNotQueriesByFilter

+

Signature: assertNotQueriesByFilter(string $filter, [string $message]) : void

+

Asserts that no queries were made as a consequence of the specified filter.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_filter('the_title', function($title, $postId){
+     $post = get_post($postId);
+     if($post->post_type !== 'book'){
+         return $title;
+     }
+     $new = get_option('acme_new_prefix');
+     return "{$new} - " . $title;
+});
+$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
+$this->assertNotQueriesByFilter('the_title');
+
+

assertNotQueriesByFunction

+

Signature: assertNotQueriesByFunction(string $function, [string $message]) : void

+

Asserts that no queries were made by the specified function.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$this->assertEmpty(Acme\get_orphaned_posts());
+Acme\delete_orphaned_posts();
+$this->assertNotQueriesByFunction('Acme\delete_orphaned_posts');
+
+

assertNotQueriesByMethod

+

Signature: assertNotQueriesByMethod(string $class, string $method, [string $message]) : void

+

Asserts that no queries have been made by the specified class method.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$options = new Acme\Options();
+$options->update('adsSource', 'not-a-real-url.org');
+$I->assertNotQueriesByMethod('Acme\Options', 'update');
+
+

assertNotQueriesByStatement

+

Signature: assertNotQueriesByStatement(string $statement, [string $message]) : void

+

Asserts that no queries have been made by the specified class method.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$bookRepository = new Acme\BookRepository();
+$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
+$this->assertNotQueriesByStatement('INSERT', 'Deferred write should happen on __destruct');
+
+

assertNotQueriesByStatementAndAction

+

Signature: assertNotQueriesByStatementAndAction(string $statement, string $action, [string $message]) : void

+

Asserts that no queries were made as a consequence of the specified action containing the SQL query.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_action( 'edit_post', function($postId){
+        $count = get_option('acme_title_updates_count');
+        update_option('acme_title_updates_count', ++$count);
+} );
+wp_delete_post($bookId);
+$this->assertNotQueriesByStatementAndAction('DELETE', 'delete_post');
+
+

assertNotQueriesByStatementAndFilter

+

Signature: assertNotQueriesByStatementAndFilter(string $statement, string $filter, [string $message]) : void

+

Asserts that no queries were made as a consequence of the specified filter containing the specified SQL query.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_filter('the_title', function($title, $postId){
+     $post = get_post($postId);
+     if($post->post_type !== 'book'){
+         return $title;
+     }
+     $new = get_option('acme_new_prefix');
+     return "{$new} - " . $title;
+});
+$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
+$this->assertNotQueriesByStatementAndFilter('SELECT', 'the_title');
+
+

assertNotQueriesByStatementAndFunction

+

Signature: assertNotQueriesByStatementAndFunction(string $statement, string $function, [string $message]) : void

+

Asserts that no queries were made by the specified function starting with the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+wp_insert_post(['ID' => $bookId, 'post_title' => 'The Call of the Wild']);
+$this->assertNotQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
+$this->assertQueriesByStatementAndFunction('UPDATE', 'wp_insert_post');
+
+

assertNotQueriesByStatementAndMethod

+

Signature: assertNotQueriesByStatementAndMethod(string $statement, string $class, string $method, [string $message]) : void

+

Asserts that no queries were made by the specified class method starting with the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
+$this->assertQueriesByStatementAndMethod('INSERT', Acme\BookRepository::class, 'commit');
+
+

assertQueries

+

Signature: assertQueries([string $message]) : void

+

Asserts that at least one query was made during the test.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+wp_cache_delete('page-posts', 'acme');
+$pagePosts = $plugin->getPagePosts();
+$I->assertQueries('Queries should be made to set the cache.')
+
+

assertQueriesByAction

+

Signature: assertQueriesByAction(string $action, [string $message]) : void

+

Asserts that at least one query was made as a consequence of the specified action.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_action( 'edit_post', function($postId){
+        $count = get_option('acme_title_updates_count');
+        update_option('acme_title_updates_count', ++$count);
+} );
+wp_update_post(['ID' => $bookId, 'post_title' => 'New Title']);
+$this->assertQueriesByAction('edit_post');
+
+

assertQueriesByFilter

+

Signature: assertQueriesByFilter(string $filter, [string $message]) : void

+

Asserts that at least one query was made as a consequence of the specified filter.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_filter('the_title', function($title, $postId){
+     $post = get_post($postId);
+     if($post->post_type !== 'book'){
+         return $title;
+     }
+     $new = get_option('acme_new_prefix');
+     return "{$new} - " . $title;
+});
+$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
+$this->assertQueriesByFilter('the_title');
+
+

assertQueriesByFunction

+

Signature: assertQueriesByFunction(string $function, [string $message]) : void

+

Asserts that queries were made by the specified function.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+acme_clean_queue();
+$this->assertQueriesByFunction('acme_clean_queue');
+
+

assertQueriesByMethod

+

Signature: assertQueriesByMethod(string $class, string $method, [string $message]) : void

+

Asserts that at least one query has been made by the specified class method.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$options = new Acme\Options();
+$options->update('showAds', false);
+$I->assertQueriesByMethod('Acme\Options', 'update');
+
+

assertQueriesByStatement

+

Signature: assertQueriesByStatement(string $statement, [string $message]) : void

+

Asserts that at least a query starting with the specified statement was made.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+wp_cache_flush();
+cached_get_posts($args);
+$I->assertQueriesByStatement('SELECT');
+
+

assertQueriesByStatementAndAction

+

Signature: assertQueriesByStatementAndAction(string $statement, string $action, [string $message]) : void

+

Asserts that at least one query was made as a consequence of the specified action containing the SQL query.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_action( 'edit_post', function($postId){
+        $count = get_option('acme_title_updates_count');
+        update_option('acme_title_updates_count', ++$count);
+} );
+wp_update_post(['ID' => $bookId, 'post_title' => 'New']);
+$this->assertQueriesByStatementAndAction('UPDATE', 'edit_post');
+
+

assertQueriesByStatementAndFilter

+

Signature: assertQueriesByStatementAndFilter(string $statement, string $filter, [string $message]) : void

+

Asserts that at least one query was made as a consequence of the specified filter containing the SQL query.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_filter('the_title', function($title, $postId){
+     $post = get_post($postId);
+     if($post->post_type !== 'book'){
+         return $title;
+     }
+     $new = get_option('acme_new_prefix');
+     return "{$new} - " . $title;
+});
+$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
+$this->assertQueriesByStatementAndFilter('SELECT', 'the_title');
+
+

assertQueriesByStatementAndFunction

+

Signature: assertQueriesByStatementAndFunction(string $statement, string $function, [string $message]) : void

+

Asserts that queries were made by the specified function starting with the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);
+$this->assertQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
+
+

assertQueriesByStatementAndMethod

+

Signature: assertQueriesByStatementAndMethod(string $statement, string $class, string $method, [string $message]) : void

+

Asserts that queries were made by the specified class method starting with the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
+$this->assertQueriesByStatementAndMethod('UPDATE', Acme\BookRepository::class, 'commit');
+
+

assertQueriesCountByAction

+

Signature: assertQueriesCountByAction(int $n, string $action, [string $message]) : void

+

Asserts that n queries were made as a consequence of the specified action.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_action( 'edit_post', function($postId){
+        $count = get_option('acme_title_updates_count');
+        update_option('acme_title_updates_count', ++$count);
+} );
+wp_update_post(['ID' => $bookOneId, 'post_title' => 'One']);
+wp_update_post(['ID' => $bookTwoId, 'post_title' => 'Two']);
+wp_update_post(['ID' => $bookThreeId, 'post_title' => 'Three']);
+$this->assertQueriesCountByAction(3, 'edit_post');
+
+

assertQueriesCountByFilter

+

Signature: assertQueriesCountByFilter(int $n, string $filter, [string $message]) : void

+

Asserts that n queries were made as a consequence of the specified filter.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_filter('the_title', function($title, $postId){
+     $post = get_post($postId);
+     if($post->post_type !== 'book'){
+         return $title;
+     }
+     $new = get_option('acme_new_prefix');
+     return "{$new} - " . $title;
+});
+$title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);
+$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
+$title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);
+$this->assertQueriesCountByFilter(2, 'the_title');
+
+

assertQueriesCountByFunction

+

Signature: assertQueriesCountByFunction(int $n, string $function, [string $message]) : void

+

Asserts that n queries were made by the specified function.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$this->assertCount(3, Acme\get_orphaned_posts());
+Acme\delete_orphaned_posts();
+$this->assertQueriesCountByFunction(3, 'Acme\delete_orphaned_posts');
+
+

assertQueriesCountByMethod

+

Signature: assertQueriesCountByMethod(int $n, string $class, string $method, [string $message]) : void

+

Asserts that n queries have been made by the specified class method.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$bookRepository = new Acme\BookRepository();
+$repository->where('ID', 23)->commit('title', 'Peter Pan');
+$repository->where('ID', 89)->commit('title', 'Moby-dick');
+$repository->where('ID', 2389)->commit('title', 'The call of the wild');
+$this->assertQueriesCountByMethod(3, 'Acme\BookRepository', 'commit');
+
+

assertQueriesCountByStatement

+

Signature: assertQueriesCountByStatement(int $n, string $statement, [string $message]) : void

+

Asserts that n queries starting with the specified statement were made.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+$bookRepository = new Acme\BookRepository();
+$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
+$repository->where('ID', 89)->set('title', 'Moby-dick', $deferred = true);
+$repository->where('ID', 2389)->set('title', 'The call of the wild', $deferred = false);
+$this->assertQueriesCountByStatement(1, 'INSERT', 'Deferred write should happen on __destruct');
+
+

assertQueriesCountByStatementAndAction

+

Signature: assertQueriesCountByStatementAndAction(int $n, string $statement, string $action, [string $message]) : void

+

Asserts that n queries were made as a consequence of the specified action containing the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_action( 'edit_post', function($postId){
+        $count = get_option('acme_title_updates_count');
+        update_option('acme_title_updates_count', ++$count);
+} );
+wp_delete_post($bookOneId);
+wp_delete_post($bookTwoId);
+wp_update_post(['ID' => $bookThreeId, 'post_title' => 'New']);
+$this->assertQueriesCountByStatementAndAction(2, 'DELETE', 'delete_post');
+$this->assertQueriesCountByStatementAndAction(1, 'INSERT', 'edit_post');
+
+

assertQueriesCountByStatementAndFilter

+

Signature: assertQueriesCountByStatementAndFilter(int $n, string $statement, string $filter, [string $message]) : void

+

Asserts that n queries were made as a consequence of the specified filter containing the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+add_filter('the_title', function($title, $postId){
+     $post = get_post($postId);
+     if($post->post_type !== 'book'){
+         return $title;
+     }
+     $new = get_option('acme_new_prefix');
+     return "{$new} - " . $title;
+});
+// Warm up the cache.
+$title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);
+// Cache is warmed up now.
+$title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);
+$title = apply_filters('the_title', get_post($bookThreeId)->post_title, $bookThreeId);
+$this->assertQueriesCountByStatementAndFilter(1, 'SELECT', 'the_title');
+
+

assertQueriesCountByStatementAndFunction

+

Signature: assertQueriesCountByStatementAndFunction(int $n, string $statement, string $function, [string $message]) : void

+

Asserts that n queries were made by the specified function starting with the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+wp_insert_post(['post_type' => 'book', 'post_title' => 'The Call of the Wild']);
+wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);
+wp_insert_post(['post_type' => 'book', 'post_title' => 'The Chocolate Factory']);
+$this->assertQueriesCountByStatementAndFunction(3, 'INSERT', 'wp_insert_post');
+
+

assertQueriesCountByStatementAndMethod

+

Signature: assertQueriesCountByStatementAndMethod(int $n, string $statement, string $class, string $method, [string $message]) : void

+

Asserts that n queries were made by the specified class method starting with the specified SQL statement.

+

Queries generated by setUp, tearDown and factory methods are excluded by default.

+
<?php
+Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
+Acme\BookRepository::new(['title' => 'Moby-Dick'])->commit();
+Acme\BookRepository::new(['title' => 'The Call of the Wild'])->commit();
+$this->assertQueriesCountByStatementAndMethod(3, 'INSERT', Acme\BookRepository::class, 'commit');
+
+

countQueries

+

Signature: countQueries([?wpdb $wpdb]) : int

+

Returns the current number of queries. +Set-up and tear-down queries performed by the test case are filtered out.

+
<?php
+// In a WPTestCase, using the global $wpdb object.
+$queriesCount = $this->queries()->countQueries();
+// In a WPTestCase, using a custom $wpdb object.
+$queriesCount = $this->queries()->countQueries($customWdbb);
+
+

getQueries

+

Signature: getQueries([?wpdb $wpdb]) : array

+

Returns the queries currently performed by the global database object or the specified one. +Set-up and tear-down queries performed by the test case are filtered out.

+
<?php
+// In a WPTestCase, using the global $wpdb object.
+$queries = $this->queries()->getQueries();
+// In a WPTestCase, using a custom $wpdb object.
+$queries = $this->queries()->getQueries($customWdbb);
+
+ + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/modules/WPWebDriver/index.html b/modules/WPWebDriver/index.html new file mode 100644 index 000000000..6af997c4f --- /dev/null +++ b/modules/WPWebDriver/index.html @@ -0,0 +1,6716 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPWebDriver - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + + + + + + + +

WPWebDriver

+ +

WPWebDriver module

+

This module drives a browser using a solution like Selenium or Chromedriver to simulate user interactions with +the WordPress project.

+

The module has full Javascript support, differently from the WPBrowser module, and can be used to test +sites that use Javascript to render the page or to make assertions that require Javascript support.

+

The method extends the Codeception WebDriver module and is used in the context of Cest and Cept test +cases.

+

Configuration

+
    +
  • browser - the browser to use; e.g. 'chrome'
  • +
  • host - the host to use; e.g. 'localhost'. This is the host of the Selenium server or the Chromedriver server.
  • +
  • port - the port to use; e.g. '4444'. This is the port of the Selenium server or the Chromedriver server.
  • +
  • path - the path to use; e.g. '/wd/hub' or '/'. Use '/' for Chrome.
  • +
  • url - required; the start URL of your WordPress project.
  • +
  • adminUsername - required; the site administrator username to use in actions like loginAsAdmin.
  • +
  • adminPassword - required; the site administrator password to use in actions like loginAsAdmin.
  • +
  • adminPath - the path to the WordPress admin directory; defaults to /wp-admin.
  • +
+

More configuration options, and their explanation, are available in the Codeception WebDriver module documentation.

+

The following is an example of the module configuration to run tests on thehttp://localhost:8080 site:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPBrowser:
+      url: 'http://localhost:8080'
+      adminUsername: 'admin'
+      adminPassword: 'password'
+      adminPath: '/wp-admin'
+      browser: chrome
+      host: 'localhost'
+      port: '4444'
+      path: '/'
+      window_size: false
+      capabilities:
+        "goog:chromeOptions":
+          args:
+            - "--headless"
+            - "--disable-gpu"
+            - "--disable-dev-shm-usage"
+            - "--proxy-server='direct://'"
+            - "--proxy-bypass-list=*"
+            - "--no-sandbox"
+
+

The following configuration uses dynamic configuration parameters to set the module configuration:

+
modules:
+  enabled:
+    lucatume\WPBrowser\Module\WPBrowser:
+      url: 'http://localhost:8080'
+      adminUsername: 'admin'
+      adminPassword: 'password'
+      adminPath: '/wp-admin'
+      browser: chrome
+      host: '%CHROME_HOST%'
+      port: '%CHROME_PORT%'
+      path: '/'
+      window_size: `1920,1080`
+      capabilities:
+        "goog:chromeOptions":
+          args:
+            - "--headless"
+            - "--disable-gpu"
+            - "--disable-dev-shm-usage"
+            - "--proxy-server='direct://'"
+            - "--proxy-bypass-list=*"
+            - "--no-sandbox"
+
+

Furthermore, the above configuration will not run Chrome in headless mode: the browser window will be visible.

+

Methods

+

The module provides the following methods:

+ + +

acceptPopup

+

Signature: acceptPopup() : void

+

Accepts the active JavaScript native popup window, as created by window.alert|window.confirm|window.prompt. +Don't confuse popups with modal windows, +as created by various libraries.

+

activatePlugin

+

Signature: activatePlugin(array|string $pluginSlug) : void

+

In the plugin administration screen activates one or more plugins clicking the "Activate" link.

+

The method will not handle authentication and navigation to the plugins administration page.

+
<?php
+// Activate a plugin.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->activatePlugin('hello-dolly');
+// Activate a list of plugins.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->activatePlugin(['hello-dolly','another-plugin']);
+
+

activateTheme

+

Signature: activateTheme(string $slug) : void

+

Activates a theme.

+

The method will not handle authentication and navigation to the themes administration page.

+

amEditingPostWithId

+

Signature: amEditingPostWithId(int $id) : void

+

Go to the admin page to edit the post with the specified ID.

+

The method will not handle authentication the admin area.

+
<?php
+$I->loginAsAdmin();
+$postId = $I->havePostInDatabase();
+$I->amEditingPostWithId($postId);
+$I->fillField('post_title', 'Post title');
+
+

amEditingUserWithId

+

Signature: amEditingUserWithId(int $id) : void

+

Go to the admin page to edit the user with the specified ID.

+

The method will not handle authentication the admin area.

+
<?php
+$I->loginAsAdmin();
+$userId = $I->haveUserInDatabase('luca', 'editor');
+$I->amEditingUserWithId($userId);
+$I->fillField('email', 'new@example.net');
+
+

amOnAdminAjaxPage

+

Signature: amOnAdminAjaxPage([array|string|null $queryVars]) : void

+

Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.

+

The method will not handle authentication, nonces or authorization.

+
<?php
+$I->amOnAdminAjaxPage(['action' => 'my-action', 'data' => ['id' => 23], 'nonce' => $nonce]);
+
+

amOnAdminPage

+

Signature: amOnAdminPage(string $page) : void

+

Go to a page in the admininstration area of the site.

+

This method will not handle authentication to the administration area.

+
<?php
+$I->loginAs('user', 'password');
+// Go to the plugins management screen.
+$I->amOnAdminPage('/plugins.php');
+
+

amOnCronPage

+

Signature: amOnCronPage([array|string|null $queryVars]) : void

+

Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

+
<?php
+// Triggers the cron job with an optional query argument.
+$I->amOnCronPage('/?some-query-var=some-value');
+
+

amOnPage

+

Signature: amOnPage($page) : void

+

amOnPagesPage

+

Signature: amOnPagesPage() : void

+

Go the "Pages" administration screen.

+

The method will not handle authentication.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPagesPage();
+$I->see('Add New');
+
+

amOnPluginsPage

+

Signature: amOnPluginsPage() : void

+

Go to the plugins administration screen.

+

The method will not handle authentication.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->activatePlugin('hello-dolly');
+
+

amOnSubdomain

+

Signature: amOnSubdomain(string $subdomain) : void

+

amOnThemesPage

+

Signature: amOnThemesPage() : void

+

Moves to the themes administration page.

+

amOnUrl

+

Signature: amOnUrl($url) : void

+

appendField

+

Signature: appendField($field, string $value) : void

+

Append the given text to the given element. +Can also add a selection to a select box.

+
<?php
+$I->appendField('#mySelectbox', 'SelectValue');
+$I->appendField('#myTextField', 'appended');
+
+

attachFile

+

Signature: attachFile($field, string $filename) : void

+

cancelPopup

+

Signature: cancelPopup() : void

+

Dismisses the active JavaScript popup, as created by window.alert, window.confirm, or window.prompt.

+

checkOption

+

Signature: checkOption($option) : void

+

clearField

+

Signature: clearField($field) : void

+

Clears given field which isn't empty.

+
<?php
+$I->clearField('#username');
+
+

click

+

Signature: click($link, [$context]) : void

+

clickWithLeftButton

+

Signature: clickWithLeftButton([$cssOrXPath], [?int $offsetX], [?int $offsetY]) : void

+

Performs click with the left mouse button on an element. +If the first parameter null then the offset is relative to the actual mouse position. +If the second and third parameters are given, +then the mouse is moved to an offset of the element's top-left corner. +Otherwise, the mouse is moved to the center of the element.

+
<?php
+$I->clickWithLeftButton(['css' => '.checkout']);
+$I->clickWithLeftButton(null, 20, 50);
+$I->clickWithLeftButton(['css' => '.checkout'], 20, 50);
+
+

clickWithRightButton

+

Signature: clickWithRightButton([$cssOrXPath], [?int $offsetX], [?int $offsetY]) : void

+

Performs contextual click with the right mouse button on an element. +If the first parameter null then the offset is relative to the actual mouse position. +If the second and third parameters are given, +then the mouse is moved to an offset of the element's top-left corner. +Otherwise, the mouse is moved to the center of the element.

+
<?php
+$I->clickWithRightButton(['css' => '.checkout']);
+$I->clickWithRightButton(null, 20, 50);
+$I->clickWithRightButton(['css' => '.checkout'], 20, 50);
+
+

closeTab

+

Signature: closeTab() : void

+

Closes current browser tab and switches to previous active tab.

+
<?php
+$I->closeTab();
+
+

deactivatePlugin

+

Signature: deactivatePlugin(array|string $pluginSlug) : void

+

In the plugin administration screen deactivate a plugin clicking the "Deactivate" link.

+

The method will not handle authentication and navigation to the plugins administration page.

+
<?php
+// Deactivate one plugin.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->deactivatePlugin('hello-dolly');
+// Deactivate a list of plugins.
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->deactivatePlugin(['hello-dolly', 'my-plugin']);
+
+

debugWebDriverLogs

+

Signature: debugWebDriverLogs([?Codeception\TestInterface $test]) : void

+

Print out latest Selenium Logs in debug mode

+

deleteSessionSnapshot

+

Signature: deleteSessionSnapshot($name) : void

+

dontSee

+

Signature: dontSee($text, [$selector]) : void

+

dontSeeCheckboxIsChecked

+

Signature: dontSeeCheckboxIsChecked($checkbox) : void

+

dontSeeCookie

+

Signature: dontSeeCookie($cookie, [array $params], [bool $showDebug]) : void

+

dontSeeCurrentUrlEquals

+

Signature: dontSeeCurrentUrlEquals(string $uri) : void

+

dontSeeCurrentUrlMatches

+

Signature: dontSeeCurrentUrlMatches(string $uri) : void

+

dontSeeElement

+

Signature: dontSeeElement($selector, [array $attributes]) : void

+

dontSeeElementInDOM

+

Signature: dontSeeElementInDOM($selector, [array $attributes]) : void

+

Opposite of seeElementInDOM.

+

dontSeeInCurrentUrl

+

Signature: dontSeeInCurrentUrl(string $uri) : void

+

dontSeeInField

+

Signature: dontSeeInField($field, $value) : void

+

dontSeeInFormFields

+

Signature: dontSeeInFormFields($formSelector, array $params) : void

+

dontSeeInPageSource

+

Signature: dontSeeInPageSource(string $text) : void

+

Checks that the page source doesn't contain the given string.

+

dontSeeInPopup

+

Signature: dontSeeInPopup(string $text) : void

+

Checks that the active JavaScript popup, +as created by window.alert|window.confirm|window.prompt, does NOT contain the given string.

+

dontSeeInSource

+

Signature: dontSeeInSource($raw) : void

+

dontSeeInTitle

+

Signature: dontSeeInTitle($title) : void

+ +

Signature: dontSeeLink(string $text, [string $url]) : void

+

dontSeeOptionIsSelected

+

Signature: dontSeeOptionIsSelected($selector, $optionText) : void

+

dontSeePluginInstalled

+

Signature: dontSeePluginInstalled(string $pluginSlug) : void

+

Assert a plugin is not installed in the plugins administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->dontSeePluginInstalled('my-plugin');
+
+

doubleClick

+

Signature: doubleClick($cssOrXPath) : void

+

Performs a double click on an element matched by CSS or XPath.

+

dragAndDrop

+

Signature: dragAndDrop($source, $target) : void

+

Performs a simple mouse drag-and-drop operation.

+
<?php
+$I->dragAndDrop('#drag', '#drop');
+
+

executeAsyncJS

+

Signature: executeAsyncJS(string $script, [array $arguments]) : void

+

Executes asynchronous JavaScript. +A callback should be executed by JavaScript to exit from a script. +Callback is passed as a last element in arguments array. +Additional arguments can be passed as array in second parameter.

+
// wait for 1200 milliseconds my running `setTimeout`
+* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
+
+$seconds = 1200; // or seconds are passed as argument
+$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
+
+

executeInSelenium

+

Signature: executeInSelenium(Closure $function) : void

+

Low-level API method. +If Codeception commands are not enough, this allows you to use Selenium WebDriver methods directly:

+
$I->executeInSelenium(function(\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
+  $webdriver->get('https://google.com');
+});
+
+

This runs in the context of the +RemoteWebDriver class. +Try not to use this command on a regular basis. +If Codeception lacks a feature you need, please implement it and submit a patch.

+

executeJS

+

Signature: executeJS(string $script, [array $arguments]) : void

+

Executes custom JavaScript.

+

This example uses jQuery to get a value and assigns that value to a PHP variable:

+
<?php
+$myVar = $I->executeJS('return $("#myField").val()');
+
+// additional arguments can be passed as array
+// Example shows `Hello World` alert:
+$I->executeJS("window.alert(arguments[0])", ['Hello world']);
+
+

fillField

+

Signature: fillField($field, $value) : void

+

grabActiveTheme

+

Signature: grabActiveTheme() : ?string

+

Returns the slug of the currently active themes.

+

The method will not handle authentication and navigation to the themes administration page.

+

grabAttributeFrom

+

Signature: grabAttributeFrom($cssOrXpath, $attribute) : ?string

+

grabAvailableThemes

+

Signature: grabAvailableThemes([string $classes]) : array

+

Returns the list of available themes.

+

The method will not handle authentication and navigation to the themes administration page.

+

grabCookie

+

Signature: grabCookie($cookie, [array $params]) : mixed

+

grabCookiesWithPattern

+

Signature: grabCookiesWithPattern(string $cookiePattern) : ?array

+

Returns all the cookies whose name matches a regex pattern.

+
<?php
+$I->loginAs('customer','password');
+$I->amOnPage('/shop');
+$cartCookies = $I->grabCookiesWithPattern("#^shop_cart\\.*#");
+
+

grabFromCurrentUrl

+

Signature: grabFromCurrentUrl([$uri]) : mixed

+

grabFullUrl

+

Signature: grabFullUrl() : string

+

Grabs the current page full URL including the query vars.

+
<?php
+$today = date('Y-m-d');
+$I->amOnPage('/concerts?date=' . $today);
+$I->assertRegExp('#\\/concerts$#', $I->grabFullUrl());
+
+

grabMultiple

+

Signature: grabMultiple($cssOrXpath, [$attribute]) : array

+

grabPageSource

+

Signature: grabPageSource() : string

+

Grabs current page source code.

+

grabTextFrom

+

Signature: grabTextFrom($cssOrXPathOrRegex) : mixed

+

grabValueFrom

+

Signature: grabValueFrom($field) : ?string

+

grabWordPressTestCookie

+

Signature: grabWordPressTestCookie([?string $name]) : ?Symfony\Component\BrowserKit\Cookie

+

Returns WordPress default test cookie object if present.

+
<?php
+// Grab the default WordPress test cookie.
+$wpTestCookie = $I->grabWordPressTestCookie();
+// Grab a customized version of the test cookie.
+$myTestCookie = $I->grabWordPressTestCookie('my_test_cookie');
+
+

loadSessionSnapshot

+

Signature: loadSessionSnapshot($name, [bool $showDebug]) : bool

+

logOut

+

Signature: logOut([string|bool $redirectTo]) : void

+

Navigate to the default WordPress logout page and click the logout link.

+
<?php
+// Log out using the `wp-login.php` form and return to the current page.
+$I->logOut(true);
+// Log out using the `wp-login.php` form and remain there.
+$I->logOut(false);
+// Log out using the `wp-login.php` form and move to another page.
+$I->logOut('/some-other-page');
+
+

loginAs

+

Signature: loginAs(string $username, string $password, [int $timeout], [int $maxAttempts]) : void

+

Login as the specified user.

+

The method will not follow redirection, after the login, to any page. +Depending on the driven browser the login might be "too fast" and the server might have not +replied with valid cookies yet; in that case the method will re-attempt the login to obtain +the cookies.

+
<?php
+$I->loginAs('user', 'password');
+$I->amOnAdminPage('/');
+$I->see('Dashboard');
+
+

loginAsAdmin

+

Signature: loginAsAdmin([int $timeout], [int $maxAttempts]) : void

+

Login as the administrator user using the credentials specified in the module configuration.

+

The method will not follow redirection, after the login, to any page.

+
<?php
+$I->loginAsAdmin();
+$I->amOnAdminPage('/');
+$I->see('Dashboard');
+
+

makeElementScreenshot

+

Signature: makeElementScreenshot($selector, [?string $name]) : void

+

Takes a screenshot of an element of the current window and saves it to tests/_output/debug.

+
<?php
+$I->amOnPage('/user/edit');
+$I->makeElementScreenshot('#dialog', 'edit_page');
+// saved to: tests/_output/debug/edit_page.png
+$I->makeElementScreenshot('#dialog');
+// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png
+
+

makeHtmlSnapshot

+

Signature: makeHtmlSnapshot([?string $name]) : void

+

makeScreenshot

+

Signature: makeScreenshot([?string $name]) : void

+

Takes a screenshot of the current window and saves it to tests/_output/debug.

+
<?php
+$I->amOnPage('/user/edit');
+$I->makeScreenshot('edit_page');
+// saved to: tests/_output/debug/edit_page.png
+$I->makeScreenshot();
+// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png
+
+

maximizeWindow

+

Signature: maximizeWindow() : void

+

Maximizes the current window.

+

moveBack

+

Signature: moveBack() : void

+

Moves back in history.

+

moveForward

+

Signature: moveForward() : void

+

Moves forward in history.

+

moveMouseOver

+

Signature: moveMouseOver([$cssOrXPath], [?int $offsetX], [?int $offsetY]) : void

+

Move mouse over the first element matched by the given locator. +If the first parameter null then the page is used. +If the second and third parameters are given, +then the mouse is moved to an offset of the element's top-left corner. +Otherwise, the mouse is moved to the center of the element.

+
<?php
+$I->moveMouseOver(['css' => '.checkout']);
+$I->moveMouseOver(null, 20, 50);
+$I->moveMouseOver(['css' => '.checkout'], 20, 50);
+
+

openNewTab

+

Signature: openNewTab() : void

+

Opens a new browser tab and switches to it.

+

<?php
+$I->openNewTab();
+
+The tab is opened with JavaScript's window.open(), which means: +* Some ad-blockers might restrict it. +* The sessionStorage is copied to the new tab (contrary to a tab that was manually opened by the user)

+

performOn

+

Signature: performOn($element, $actions, [int $timeout]) : void

+

Waits for element and runs a sequence of actions inside its context. +Actions can be defined with array, callback, or Codeception\Util\ActionSequence instance.

+

Actions as array are recommended for simple to combine "waitForElement" with assertions; +waitForElement($el) and see('text', $el) can be simplified to:

+
<?php
+$I->performOn($el, ['see' => 'text']);
+
+

List of actions can be pragmatically build using Codeception\Util\ActionSequence:

+
<?php
+$I->performOn('.model', ActionSequence::build()
+    ->see('Warning')
+    ->see('Are you sure you want to delete this?')
+    ->click('Yes')
+);
+
+

Actions executed from array or ActionSequence will print debug output for actions, and adds an action name to +exception on failure.

+

Whenever you need to define more actions a callback can be used. A WebDriver module is passed for argument:

+
<?php
+$I->performOn('.rememberMe', function (WebDriver $I) {
+     $I->see('Remember me next time');
+     $I->seeElement('#LoginForm_rememberMe');
+     $I->dontSee('Login');
+});
+
+

In 3rd argument you can set number a seconds to wait for element to appear

+

pressKey

+

Signature: pressKey($element, [...$chars]) : void

+

Presses the given key on the given element. +To specify a character and modifier (e.g. Ctrl, Alt, Shift, Meta), pass an array for $char with +the modifier as the first element and the character as the second. +For special keys, use the constants from Facebook\WebDriver\WebDriverKeys.

+
<?php
+// <input id="page" value="old" />
+$I->pressKey('#page','a'); // => olda
+$I->pressKey('#page',array('ctrl','a'),'new'); //=> new
+$I->pressKey('#page',array('shift','111'),'1','x'); //=> old!!!1x
+$I->pressKey('descendant-or-self::*[@id='page']','u'); //=> oldu
+$I->pressKey('#name', array('ctrl', 'a'), \Facebook\WebDriver\WebDriverKeys::DELETE); //=>''
+
+

reloadPage

+

Signature: reloadPage() : void

+

Reloads the current page.

+

resetCookie

+

Signature: resetCookie($cookie, [array $params], [bool $showDebug]) : void

+

resizeWindow

+

Signature: resizeWindow(int $width, int $height) : void

+

Resize the current window.

+
<?php
+$I->resizeWindow(800, 600);
+
+

saveSessionSnapshot

+

Signature: saveSessionSnapshot($name) : void

+

scrollTo

+

Signature: scrollTo($selector, [?int $offsetX], [?int $offsetY]) : void

+

Move to the middle of the given element matched by the given locator. +Extra shift, calculated from the top-left corner of the element, +can be set by passing $offsetX and $offsetY parameters.

+
<?php
+$I->scrollTo(['css' => '.checkout'], 20, 50);
+
+

see

+

Signature: see($text, [$selector]) : void

+

seeCheckboxIsChecked

+

Signature: seeCheckboxIsChecked($checkbox) : void

+

seeCookie

+

Signature: seeCookie($cookie, [array $params], [bool $showDebug]) : void

+

seeCurrentUrlEquals

+

Signature: seeCurrentUrlEquals(string $uri) : void

+

seeCurrentUrlMatches

+

Signature: seeCurrentUrlMatches(string $uri) : void

+

seeElement

+

Signature: seeElement($selector, [array $attributes]) : void

+

seeElementInDOM

+

Signature: seeElementInDOM($selector, [array $attributes]) : void

+

Checks that the given element exists on the page, even it is invisible.

+
<?php
+$I->seeElementInDOM('//form/input[type=hidden]');
+
+

seeErrorMessage

+

Signature: seeErrorMessage([array|string $classes]) : void

+

In an administration screen look for an error admin notice.

+

The check is class-based to decouple from internationalization. +The method will not handle authentication and navigation the administration area.

+
<?php
+$I->loginAsAdmin()
+$I->amOnAdminPage('/');
+$I->seeErrorMessage('.my-plugin');
+
+

seeInCurrentUrl

+

Signature: seeInCurrentUrl(string $uri) : void

+

seeInField

+

Signature: seeInField($field, $value) : void

+

seeInFormFields

+

Signature: seeInFormFields($formSelector, array $params) : void

+

seeInPageSource

+

Signature: seeInPageSource(string $text) : void

+

Checks that the page source contains the given string.

+
<?php
+$I->seeInPageSource('<link rel="apple-touch-icon"');
+
+

seeInPopup

+

Signature: seeInPopup(string $text) : void

+

Checks that the active JavaScript popup, +as created by window.alert|window.confirm|window.prompt, contains the given string.

+

seeInSource

+

Signature: seeInSource($raw) : void

+

seeInTitle

+

Signature: seeInTitle($title) : void

+ +

Signature: seeLink(string $text, [?string $url]) : void

+

seeMessage

+

Signature: seeMessage([array|string $classes]) : void

+

In an administration screen look for an admin notice.

+

The check is class-based to decouple from internationalization. +The method will not handle authentication and navigation the administration area.

+
<?php
+$I->loginAsAdmin()
+$I->amOnAdminPage('/');
+$I->seeMessage('.missing-api-token.my-plugin');
+
+

seeNumberOfElements

+

Signature: seeNumberOfElements($selector, $expected) : void

+

seeNumberOfElementsInDOM

+

Signature: seeNumberOfElementsInDOM($selector, $expected) : void

+

seeNumberOfTabs

+

Signature: seeNumberOfTabs(int $number) : void

+

Checks current number of opened tabs

+
<?php
+$I->seeNumberOfTabs(2);
+
+

seeOptionIsSelected

+

Signature: seeOptionIsSelected($selector, $optionText) : void

+

seePluginActivated

+

Signature: seePluginActivated(string $pluginSlug) : void

+

Assert a plugin is activated in the plugin administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->seePluginActivated('my-plugin');
+
+

seePluginDeactivated

+

Signature: seePluginDeactivated(string $pluginSlug) : void

+

Assert a plugin is not activated in the plugins administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->seePluginDeactivated('my-plugin');
+
+

seePluginInstalled

+

Signature: seePluginInstalled(string $pluginSlug) : void

+

Assert a plugin is installed, no matter its activation status, in the plugin administration screen.

+

The method will not handle authentication and navigation to the plugin administration screen.

+
<?php
+$I->loginAsAdmin();
+$I->amOnPluginsPage();
+$I->seePluginInstalled('my-plugin');
+
+

seeThemeActivated

+

Signature: seeThemeActivated(string $slug) : void

+

Verifies that a theme is active.

+

The method will not handle authentication and navigation to the themes administration page.

+

seeWpDiePage

+

Signature: seeWpDiePage() : void

+

Checks that the current page is one generated by the wp_die function.

+

The method will try to identify the page based on the default WordPress die page HTML attributes.

+
<?php
+$I->loginAs('user', 'password');
+$I->amOnAdminPage('/forbidden');
+$I->seeWpDiePage();
+
+

selectOption

+

Signature: selectOption($select, $option) : void

+

setCookie

+

Signature: setCookie($name, $value, [array $params], [$showDebug]) : void

+

submitForm

+

Signature: submitForm($selector, array $params, [$button]) : void

+

Submits the given form on the page, optionally with the given form +values. Give the form fields values as an array. Note that hidden fields +can't be accessed.

+

Skipped fields will be filled by their values from the page. +You don't need to click the 'Submit' button afterwards. +This command itself triggers the request to form's action.

+

You can optionally specify what button's value to include +in the request with the last parameter as an alternative to +explicitly setting its value in the second parameter, as +button values are not otherwise included in the request.

+

Examples:

+
<?php
+$I->submitForm('#login', [
+    'login' => 'davert',
+    'password' => '123456'
+]);
+// or
+$I->submitForm('#login', [
+    'login' => 'davert',
+    'password' => '123456'
+], 'submitButtonName');
+
+

For example, given this sample "Sign Up" form:

+
<form action="/sign_up">
+    Login:
+    <input type="text" name="user[login]" /><br/>
+    Password:
+    <input type="password" name="user[password]" /><br/>
+    Do you agree to our terms?
+    <input type="checkbox" name="user[agree]" /><br/>
+    Select pricing plan:
+    <select name="plan">
+        <option value="1">Free</option>
+        <option value="2" selected="selected">Paid</option>
+    </select>
+    <input type="submit" name="submitButton" value="Submit" />
+</form>
+
+

You could write the following to submit it:

+

<?php
+$I->submitForm(
+    '#userForm',
+    [
+        'user[login]' => 'Davert',
+        'user[password]' => '123456',
+        'user[agree]' => true
+    ],
+    'submitButton'
+);
+
+Note that "2" will be the submitted value for the "plan" field, as it is +the selected option.

+

Also note that this differs from PhpBrowser, in that +'user' => [ 'login' => 'Davert' ] is not supported at the moment. +Named array keys must be included in the name as above.

+

Pair this with seeInFormFields for quick testing magic.

+
<?php
+$form = [
+     'field1' => 'value',
+     'field2' => 'another value',
+     'checkbox1' => true,
+     // ...
+];
+$I->submitForm('//form[@id=my-form]', $form, 'submitButton');
+// $I->amOnPage('/path/to/form-page') may be needed
+$I->seeInFormFields('//form[@id=my-form]', $form);
+
+

Parameter values must be set to arrays for multiple input fields +of the same name, or multi-select combo boxes. For checkboxes, +either the string value can be used, or boolean values which will +be replaced by the checkbox's value in the DOM.

+
<?php
+$I->submitForm('#my-form', [
+     'field1' => 'value',
+     'checkbox' => [
+         'value of first checkbox',
+         'value of second checkbox',
+     ],
+     'otherCheckboxes' => [
+         true,
+         false,
+         false,
+     ],
+     'multiselect' => [
+         'first option value',
+         'second option value',
+     ]
+]);
+
+

Mixing string and boolean values for a checkbox's value is not supported +and may produce unexpected results.

+

Field names ending in "[]" must be passed without the trailing square +bracket characters, and must contain an array for its value. This allows +submitting multiple values with the same name, consider:

+
<?php
+$I->submitForm('#my-form', [
+    'field[]' => 'value',
+    'field[]' => 'another value', // 'field[]' is already a defined key
+]);
+
+

The solution is to pass an array value:

+
<?php
+// this way both values are submitted
+$I->submitForm('#my-form', [
+    'field' => [
+        'value',
+        'another value',
+    ]
+]);
+
+

The $button parameter can be either a string, an array or an instance +of Facebook\WebDriver\WebDriverBy. When it is a string, the +button will be found by its "name" attribute. If $button is an +array then it will be treated as a strict selector and a WebDriverBy +will be used verbatim.

+

For example, given the following HTML:

+
<input type="submit" name="submitButton" value="Submit" />
+
+

$button could be any one of the following: + - 'submitButton' + - ['name' => 'submitButton'] + - WebDriverBy::name('submitButton')

+

switchToFrame

+

Signature: switchToFrame([?string $locator]) : void

+

Switch to another frame on the page.

+

Example: +

<frame name="another_frame" id="fr1" src="https://example.com">
+

+
<?php
+# switch to frame by name
+$I->switchToFrame("another_frame");
+# switch to frame by CSS or XPath
+$I->switchToFrame("#fr1");
+# switch to parent page
+$I->switchToFrame();
+
+

switchToIFrame

+

Signature: switchToIFrame([?string $locator]) : void

+

Switch to another iframe on the page.

+

Example: +

<iframe name="another_frame" id="fr1" src="https://example.com">
+

+
<?php
+# switch to iframe by name
+$I->switchToIFrame("another_frame");
+# switch to iframe by CSS or XPath
+$I->switchToIFrame("#fr1");
+# switch to parent page
+$I->switchToIFrame();
+
+

switchToNextTab

+

Signature: switchToNextTab([int $offset]) : void

+

Switches to next browser tab. +An offset can be specified.

+
<?php
+// switch to next tab
+$I->switchToNextTab();
+// switch to 2nd next tab
+$I->switchToNextTab(2);
+
+

switchToPreviousTab

+

Signature: switchToPreviousTab([int $offset]) : void

+

Switches to previous browser tab. +An offset can be specified.

+
<?php
+// switch to previous tab
+$I->switchToPreviousTab();
+// switch to 2nd previous tab
+$I->switchToPreviousTab(2);
+
+

switchToWindow

+

Signature: switchToWindow([?string $name]) : void

+

Switch to another window identified by name.

+

The window can only be identified by name. If the $name parameter is blank, the parent window will be used.

+

Example: +

<input type="button" value="Open window" onclick="window.open('https://example.com', 'another_window')">
+

+
<?php
+$I->click("Open window");
+# switch to another window
+$I->switchToWindow("another_window");
+# switch to parent window
+$I->switchToWindow();
+
+

If the window has no name, match it by switching to next active tab using switchToNextTab method.

+

Or use native Selenium functions to get access to all opened windows:

+
<?php
+$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
+     $handles=$webdriver->getWindowHandles();
+     $last_window = end($handles);
+     $webdriver->switchTo()->window($last_window);
+});
+
+

type

+

Signature: type(string $text, [int $delay]) : void

+

Type in characters on active element. +With a second parameter you can specify delay between key presses.

+
<?php
+// activate input element
+$I->click('#input');
+
+// type text in active element
+$I->type('Hello world');
+
+// type text with a 1sec delay between chars
+$I->type('Hello World', 1);
+
+

This might be useful when you an input reacts to typing and you need to slow it down to emulate human behavior. +For instance, this is how Credit Card fields can be filled in.

+

typeInPopup

+

Signature: typeInPopup(string $keys) : void

+

Enters text into a native JavaScript prompt popup, as created by window.prompt.

+

uncheckOption

+

Signature: uncheckOption($option) : void

+

unselectOption

+

Signature: unselectOption($select, $option) : void

+

Unselect an option in the given select box.

+

wait

+

Signature: wait($timeout) : void

+

Wait for $timeout seconds.

+

waitForElement

+

Signature: waitForElement($element, [int $timeout]) : void

+

Waits up to $timeout seconds for an element to appear on the page. +If the element doesn't appear, a timeout exception is thrown.

+
<?php
+$I->waitForElement('#agree_button', 30); // secs
+$I->click('#agree_button');
+
+

waitForElementChange

+

Signature: waitForElementChange($element, Closure $callback, [int $timeout]) : void

+

Waits up to $timeout seconds for the given element to change. +Element "change" is determined by a callback function which is called repeatedly +until the return value evaluates to true.

+
<?php
+use \Facebook\WebDriver\WebDriverElement
+$I->waitForElementChange('#menu', function(WebDriverElement $el) {
+    return $el->isDisplayed();
+}, 100);
+
+

waitForElementClickable

+

Signature: waitForElementClickable($element, [int $timeout]) : void

+

Waits up to $timeout seconds for the given element to be clickable. +If element doesn't become clickable, a timeout exception is thrown.

+
<?php
+$I->waitForElementClickable('#agree_button', 30); // secs
+$I->click('#agree_button');
+
+

waitForElementNotVisible

+

Signature: waitForElementNotVisible($element, [int $timeout]) : void

+

Waits up to $timeout seconds for the given element to become invisible. +If element stays visible, a timeout exception is thrown.

+
<?php
+$I->waitForElementNotVisible('#agree_button', 30); // secs
+
+

waitForElementVisible

+

Signature: waitForElementVisible($element, [int $timeout]) : void

+

Waits up to $timeout seconds for the given element to be visible on the page. +If element doesn't appear, a timeout exception is thrown.

+
<?php
+$I->waitForElementVisible('#agree_button', 30); // secs
+$I->click('#agree_button');
+
+

waitForJS

+

Signature: waitForJS(string $script, [int $timeout]) : void

+

Executes JavaScript and waits up to $timeout seconds for it to return true.

+

In this example we will wait up to 60 seconds for all jQuery AJAX requests to finish.

+
<?php
+$I->waitForJS("return $.active == 0;", 60);
+
+

waitForJqueryAjax

+

Signature: waitForJqueryAjax([int $time]) : void

+

Waits for any jQuery triggered AJAX request to be resolved.

+
<?php
+$I->amOnPage('/triggering-ajax-requests');
+$I->waitForJqueryAjax();
+$I->see('From AJAX');
+
+

waitForText

+

Signature: waitForText(string $text, [int $timeout], [$selector]) : void

+

Waits up to $timeout seconds for the given string to appear on the page.

+

Can also be passed a selector to search in, be as specific as possible when using selectors. +waitForText() will only watch the first instance of the matching selector / text provided. +If the given text doesn't appear, a timeout exception is thrown.

+
<?php
+$I->waitForText('foo', 30); // secs
+$I->waitForText('foo', 30, '.title'); // secs
+
+ + +

Read more in Codeception documentation.

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 000000000..335d70cad --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Getting started","text":"

This is the documentation for version 4 of the project, the current version. Documentation for the previous version of the project, version 3, can be found here.

The wp-browser library provides a set of Codeception modules and middleware to enable the testing of WordPress sites, plugins and themes.

"},{"location":"#requirements","title":"Requirements","text":"

Depending on the nature of your project, there are different requirements it will need to satisfy before getting started.

"},{"location":"#site","title":"Site","text":"
  • Ensure you're running the vendor/bin/codecept init wpbrowser command from the root directory of your WordPress site.
  • Ensure the directory contains the WordPress installation files. In a standard scenario you should have extracted WordPress files in this directory.
  • Ensure your installation is configured: it should contain a wp-config.php file.
"},{"location":"#plugin","title":"Plugin","text":"
  • Ensure you're running the vendor/bin/codecept init wpbrowser command from the root directory of your plugin; this should be the directory that contains the PHP file defining the plugin header.
"},{"location":"#theme","title":"Theme","text":"
  • Ensure you're running the vendor/bin/codecept init wpbrowser command from the root directory of your theme; this should be the directory that contains the style.css file defining the theme header.

If you decide to use the quick installation, then your PHP version should have the sqlite3 extensions installed and activated. You can check this using the php -m command and verifying the sqlite3 extension is among the active extensions.

"},{"location":"#installation","title":"Installation","text":"

Add wp-browser to your project as a development dependency using Composer

cd my-wordrpess-project\ncomposer require --dev lucatume/wp-browser\n

Initialize wp-browser to quickly configured to suite your project and setup:

vendor/bin/codecept init wpbrowser\n

The command will set up your project to run integration and end-to-end tests using:

  • SQLite as the database engine, leveraging the SQLite Database Integration plugin
  • PHP built-in web server to serve the WordPress site on localhost (e.g. http://localhost:8080)
  • Chromedriver to drive the local version of Chrome installed on your machine

If you're working on a plugin or theme project, the default configuration will add some extra steps:

  • install the latest version of WordPress in the tests/_wordpress directory
  • create a tests/_plugins directory: any file or directory in this directory will be symlinked into the WordPress installation in tests/_wordpress/wp-content/plugins
  • create a tests/_themes directory: any file or directory in this directory will be symlinked into the WordPress installation in tests/_wordpress/wp-content/themes

For most projects this configuration will be enough to get started with testing.

You can run your tests immediately using the vendor/bin/codecept run command.

Read more about the commands provided by the library here.

"},{"location":"#using-a-custom-configuration","title":"Using a custom configuration","text":"

If you decide to skip the default configuration, you will be able to set up wp-browser to suit your needs and local setup by editing the tests/.env file. The inline documentation in the file will guide you through the configuration process.

Read more about using a custom configuration here.

"},{"location":"#getting-support-for-wp-browser-configuration-and-usage","title":"Getting support for wp-browser configuration and usage","text":"

The best place to get support for wp-browser is the project documentation. Since this project builds on top of PHPUnit and Codeception, you can also refer to their documentation.

If you can't find the answer to your question here you can ask on the \"Issues\" section of the wp-browser repository taking care to provide as much information as possible.

Finally, you can contact me directly to set up a call to discuss your project needs and how wp-browser can help you.

"},{"location":"DispatcherAPI/","title":"Dispatcher API","text":"

An API to dispatch and subscribe to events fired during tests execution.

"},{"location":"DispatcherAPI/#events-dispatched-by-codeception","title":"Events dispatched by Codeception","text":"

You can subscribe to the following events dispatched by Codeception in either the global bootstrap file (usually tests/_bootstrap.php), or in a suite bootstrap file (usually tests/<suite>/_bootstrap.php) using the Event Dispatcher Bridge extension:

  • Codeception\\Events::SUITE_BEFORE
  • Codeception\\Events::SUITE_AFTER
  • CodeceptionventsEvents::TEST_START
  • CodeceptionventsEvents::TEST_BEFORE
  • CodeceptionventsEvents::STEP_BEFORE
  • CodeceptionventsEvents::STEP_AFTER
  • CodeceptionventsEvents::TEST_FAIL
  • CodeceptionventsEvents::TEST_ERROR
  • CodeceptionventsEvents::TEST_PARSED
  • CodeceptionventsEvents::TEST_INCOMPLETE
  • CodeceptionventsEvents::TEST_SKIPPED
  • CodeceptionventsEvents::TEST_WARNING
  • CodeceptionventsEvents::TEST_USELESS
  • CodeceptionventsEvents::TEST_SUCCESS
  • CodeceptionventsEvents::TEST_AFTER
  • CodeceptionventsEvents::TEST_END
  • CodeceptionventsEvents::TEST_FAIL_PRINT
  • CodeceptionventsEvents::RESULT_PRINT_AFTER

In the global bootstrap file (usually tests/_bootstrap.php), or the suite bootstrap file (usually tests/<suite>/_bootstrap.php), subscribe to the Codeception events by providing a callback function that will accept different parameters depending on the event being dispatched:

<?php\n\nuse Codeception\\Events;\nuse Codeception\\Event\\SuiteEvent\nuse Codeception\\Event\\TestEvent;\nuse Codeception\\Event\\StepEvent;\nuse Codeception\\Event\\PrintResultEvent;\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\n\nDispatcher::addListener(Events::SUITE_BEFORE, function (SuiteEvent $suiteEvent) {\n    codecept_debug('Running on SUITE BEFORE');\n});\n\nDispatcher::addListener(Events::SUITE_AFTER, function (SuiteEvent $suiteEvent) {\n    codecept_debug('Running on SUITE AFTER');\n});\n\nDispatcher::addListener(Events::TEST_START, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST START');\n});\n\nDispatcher::addListener(Events::TEST_BEFORE, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST BEFORE');\n});\n\nDispatcher::addListener(Events::STEP_BEFORE, function (StepEvent $stepEvent) {\n    codecept_debug('Running on STEP BEFORE');\n});\n\nDispatcher::addListener(Events::STEP_AFTER, function (StepEvent $stepEvent) {\n    codecept_debug('Running on STEP AFTER');\n});\n\nDispatcher::addListener(Events::TEST_FAIL, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST FAIL');\n});\n\nDispatcher::addListener(Events::TEST_ERROR, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST ERROR');\n});\n\nDispatcher::addListener(Events::TEST_PARSED, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST PARSED');\n});\n\nDispatcher::addListener(Events::TEST_INCOMPLETE, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST INCOMPLETE');\n});\n\nDispatcher::addListener(Events::TEST_SKIPPED, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST SKIPPED');\n});\n\nDispatcher::addListener(Events::TEST_WARNING, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST WARNING');\n});\n\nDispatcher::addListener(Events::TEST_USELESS, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST USELESS');\n});\n\nDispatcher::addListener(Events::TEST_SUCCESS, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST SUCCESS');\n});\n\nDispatcher::addListener(Events::TEST_AFTER, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST AFTER');\n});\n\nDispatcher::addListener(Events::TEST_END, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST END');\n});\n\nDispatcher::addListener(Events::TEST_FAIL_PRINT, function (PrintResultEvent $printResultEvent) {\n    codecept_debug('Running on TEST FAIL PRINT');\n});\n\nDispatcher::addListener(Events::RESULT_PRINT_AFTER, function (PrintResultEvent $printResultEvent) {\n    codecept_debug('Running on RESULT PRINT AFTER');\n});\n
"},{"location":"DispatcherAPI/#events-dispatched-by-wp-browser","title":"Events dispatched by wp-browser","text":"

The project dispatches its own events, allowing you to subscribe to them to control the test state and execution. To subscribe to the events dispatched by wp-browser, you do not need to use the Event Dispatcher Bridge extension.

"},{"location":"DispatcherAPI/#events-dispatched-by-the-wploader-module","title":"Events dispatched by the WPLoader module","text":"

The WPLoader module will dispatch events during its initialization.

"},{"location":"DispatcherAPI/#event_before_loadonly","title":"EVENT_BEFORE_LOADONLY","text":"

This event fires before WordPress is loaded by the WPLoader module when loadOnly is set to true.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

WordPress is not loaded yet, so you cannot use functions or classes defined by WordPress, themes or plugins here. You can interact with the WordPress installation and use the lucatume\\WPBrowser\\WordPress\\PreloadFilters class to hook on actions and filters that will be fired by WordPress once loaded.

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPLoader;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPLoader::EVENT_BEFORE_LOADONLY, function (Event $event) {\n    /** @var WPLoader $wpLoader */\n    $wpLoader = $event->getOrigin();\n\n    codecept_debug('Running on EVENT_BEFORE_LOADONLY');\n\n    // Interact with the WordPress installation, its filesystem and database.\n    $installation = $wpLoader->getInstallation();\n    $pluginsDir = $installation->getPluginsDir();\n    $db = $installation->getDb();\n    $db->import(codecept_data_dir('some-dump.sql'));\n\n    // Use the PreloadFilters class to hook on WordPress actions and filters.\n    PreloadFilters::addFilter('init', fn() => update_option('some_option', 'some_value'));\n    PreloadFilters::addFilter('pre_option_some_option', fn() => 'some_value');\n});\n
"},{"location":"DispatcherAPI/#event_after_loadonly","title":"EVENT_AFTER_LOADONLY","text":"

This event fires after WordPress is loaded by the WPLoader module when loadOnly is set to true.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

At this point, WordPress has been loaded. You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins.

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPLoader;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPLoader::EVENT_AFTER_LOADONLY, function (Event $event) {\n    /** @var WPLoader $wpLoader */\n    $wpLoader = $event->getOrigin();\n\n    codecept_debug('Running on EVENT_AFTER_LOADONLY');\n\n    // Interact with the WordPress installation, its filesystem and database.    \n    $installation = $wpLoader->getInstallation();\n    $pluginsDir = $installation->getPluginsDir();\n    $db = $installation->getDb();\n    $db->import(codecept_data_dir('some-dump.sql'));\n\n    // Use WordPress functions and classes.\n    update_option('some_option', 'some_value');\n});\n
"},{"location":"DispatcherAPI/#event_before_install","title":"EVENT_BEFORE_INSTALL","text":"

This event fires before WordPress is installed by the WPLoader module when loadOnly is set to false.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

WordPress is not loaded yet, so you cannot use functions or classes defined by WordPress, themes or plugins here. You can interact with the WordPress installation and use the lucatume\\WPBrowser\\WordPress\\PreloadFilters class to hook on actions and filters that will be fired by WordPress once loaded.

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPLoader;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPLoader::EVENT_BEFORE_INSTALL, function (Event $event) {\n    /** @var WPLoader $wpLoader */\n    $wpLoader = $event->getOrigin();\n\n    codecept_debug('Running on EVENT_BEFORE_INSTALL');\n\n    // Interact with the WordPress installation, its filesystem and database.\n    $installation = $wpLoader->getInstallation();\n    $pluginsDir = $installation->getPluginsDir();\n    $db = $installation->getDb();\n    $db->import(codecept_data_dir('some-dump.sql'));\n\n    // Use the PreloadFilters class to hook on WordPress actions and filters.\n    PreloadFilters::addFilter('init', fn() => update_option('some_option', 'some_value'));\n    PreloadFilters::addFilter('pre_option_some_option', fn() => 'some_value');\n});\n
"},{"location":"DispatcherAPI/#event_after_install","title":"EVENT_AFTER_INSTALL","text":"

This event fires after WordPress is installed by the WPLoader module when loadOnly is set to false.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

At this point, WordPress has been installed and loaded. You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins. This event fires before dump files specified in the dump configuration parameter of the WPLoader module are imported.

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPLoader;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPLoader::EVENT_AFTER_INSTALL, function (Event $event) {\n    /** @var WPLoader $wpLoader */\n    $wpLoader = $event->getOrigin();\n\n    codecept_debug('Running on EVENT_AFTER_INSTALL');\n\n    // Interact with the WordPress installation, its filesystem and database.    \n    $installation = $wpLoader->getInstallation();\n    $pluginsDir = $installation->getPluginsDir();\n    $db = $installation->getDb();\n    $db->import(codecept_data_dir('some-dump.sql'));\n\n    // Use WordPress functions and classes.    \n    update_option('some_option', 'some_value');\n});\n
"},{"location":"DispatcherAPI/#event_after_install_1","title":"EVENT_AFTER_INSTALL","text":"

This event fires after WordPress is installed by the WPLoader module when loadOnly is set to false.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

At this point, WordPress has been installed and loaded. You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins.

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPLoader;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPLoader::EVENT_AFTER_INSTALL, function (Event $event) {\n    /** @var WPLoader $wpLoader */\n    $wpLoader = $event->getOrigin();\n\n    codecept_debug('Running on EVENT_AFTER_INSTALL');\n\n    // Interact with the WordPress installation, its filesystem and database.    \n    $installation = $wpLoader->getInstallation();\n    $pluginsDir = $installation->getPluginsDir();\n    $db = $installation->getDb();\n    $db->import(codecept_data_dir('some-dump.sql'));\n\n    // Use WordPress functions and classes.\n    update_option('some_option', 'some_value');\n});\n
"},{"location":"DispatcherAPI/#event_after_bootstrap","title":"EVENT_AFTER_BOOTSTRAP","text":"

This event fires after the WPLoader module has finished bootstrapping the WordPress installation and dump files specified in the dump configuration parameter of the WPLoader module are imported.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

You can interact with the WordPress installation using functions and classes defined by WordPress, themes or plugins.

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPLoader;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPLoader::EVENT_AFTER_BOOTSTRAP, function (Event $event) {\n    /** @var WPLoader $wpLoader */\n    $wpLoader = $event->getOrigin();\n\n    codecept_debug('Running on EVENT_AFTER_BOOTSTRAP');\n\n    // Interact with the WordPress installation, its filesystem and database.    \n    $installation = $wpLoader->getInstallation();\n    $pluginsDir = $installation->getPluginsDir();\n    $db = $installation->getDb();\n    $db->import(codecept_data_dir('some-dump.sql'));\n\n    // Use WordPress functions and classes.\n    update_option('some_option', 'some_value');\n});\n
"},{"location":"DispatcherAPI/#events-dispatched-by-the-wpdb-module","title":"Events dispatched by the WPDb module","text":""},{"location":"DispatcherAPI/#event_before_suite","title":"EVENT_BEFORE_SUITE","text":"

This event fires after the WPDb module has run its _beforeSuite method.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

At this point the module has connected to the database, cleaned up and populated the database with the dump files.

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPDb;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPDb::EVENT_BEFORE_SUITE, function (Event $event) {\n    /** @var WPDb $wpDb */\n    $wpDb = $event->getOrigin();    \n\n    codecept_debug('Running on EVENT_BEFORE_SUIT\n    E');\n});\n
"},{"location":"DispatcherAPI/#event_before_initialize","title":"EVENT_BEFORE_INITIALIZE","text":"

This event fires before the WPDb module initializes.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Module\\WPDb;\nuse lucatume\\WPBrowser\\Events\\Event;\n\nDispatcher::addListener(WPDb::EVENT_BEFORE_INITIALIZE, function (Event $event) {\n    /** @var WPDb $wpDb */\n    $wpDb = $event->getOrigin();    \n\n    codecept_debug('Running on EVENT_BEFORE_INITIALIZE');\n});\n
"},{"location":"DispatcherAPI/#event_after_initialize","title":"EVENT_AFTER_INITIALIZE","text":"

This event fires after the WPDb module has initialized.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;  \nuse lucatume\\WPBrowser\\Module\\WPDb;  \nuse lucatume\\WPBrowser\\Events\\Event;  \n\nDispatcher::addListener(WPDb::EVENT_AFTER_INITIALIZE, function (Event $event) {\n    /** @var WPDb $wpDb */\n    $wpDb = $event->getOrigin();    \n\n    codecept_debug('Running on EVENT_AFTER_INITIALIZE');\n});\n
"},{"location":"DispatcherAPI/#event_after_db_prepare","title":"EVENT_AFTER_DB_PREPARE","text":"

This event fires after the WPDb module has prepared the database setting up some default values for quality-of-life improvements.

Due to order-of-operations, you can hook on this event only in the global bootstrap file (usually tests/_bootstrap.php).

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;  \nuse lucatume\\WPBrowser\\Module\\WPDb;  \nuse lucatume\\WPBrowser\\Events\\Event;  \n\nDispatcher::addListener(WPDb::EVENT_AFTER_DB_PREPARE, function (Event $event) {\n    /** @var WPDb $wpDb */\n    $wpDb = $event->getOrigin();    \n\n    codecept_debug('Running on EVENT_AFTER_DB_PREPARE');\n});\n
"},{"location":"DispatcherAPI/#dispatching-custom-events","title":"Dispatching custom events","text":"

You can use the Dispatcher::dispatch method to dispatch and subscribe to custom events:

<?php\n\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\nuse lucatume\\WPBrowser\\Events\\Event;  \n\nDispatcher::dispatch('my-event', 'my-origin', ['foo' => 'bar']);\n\n// Some other code...\nDispatcher::addListener('my-event', function (Event $event) {\n    $origin = $event->getOrigin();\n    $foo = $event->get('foo');\n    codecept_debug('Running on my custom event');\n});\n
"},{"location":"commands/","title":"Commands","text":""},{"location":"commands/#codeception-commands-provided-by-the-library","title":"Codeception commands provided by the library","text":"

The library provides some custom commands that can be added to the project Codeception configuration file ( either codeception.yml or codeception.dist.yml).

"},{"location":"commands/#run-and-codeceptionrun","title":"run and codeception:run","text":"

Enable the commands with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\RunOriginal\"\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\RunAll\"\n

WordPress extensive use of global variables, constants and side effectes makes it difficult to run multiple test suites in the same process without running into conflicts due to leaking state and side effects. For this reason the project replaces Codeception run command with one that will run each suite in a separate process. You can invoke the original Codeception command using the codeception:run command. Just like the original, the run command accepts all the arguments and options of the original Codeception command.

Run all the suites, each one in a separate process:

vendor/bin/codecept run\n

Run only the Integration suite:

vendor/bin/codecept run Integration\n

Run a specific test file:

vendor/bin/codecept run Integration tests/Integration/MyTest.php\n

Run a specific test method:

vendor/bin/codecept run Integration tests/Integration/MyTest.php:testMyMethod\n

Read the Codeception documentation for more information about the run command.

"},{"location":"commands/#devstart","title":"dev:start","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DevStart\"\n

If not already running, start the services required to run the tests. The started services are read from the Codeception configuration file (either codeception.yml or codeception.dist.yml), from the extensions section, under the config key.

Given the following configuration:

extensions:\n  enabled:\n    - lucatume\\WPBrowser\\Extension\\ChromeDriverController\n    - lucatume\\WPBrowser\\Extension\\BuiltInServerController\n    - lucatume\\WPBrowser\\Extension\\DockerComposeController\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\ChromeDriverController\":\n      port: '%CHROMEDRIVER_PORT%'\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\BuiltInServerController\":\n      docroot: '%WORDPRESS_ROOT_DIR%'\n      workers: 5\n      port: '%BUILT_IN_SERVER_PORT%'\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\DockerComposeController\":\n      compose-file: 'tests/docker-compose.yml'\n      env-file: 'tests/.env'\n

Running the command will start ChromeDriver, the built-in PHP server and Docker Compose.

"},{"location":"commands/#devstop","title":"dev:stop","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DevStop\"\n

If running, stop the services required to run the tests. The stopped services are read from the Codeception configuration file (either codeception.yml or codeception.dist.yml), from the extensions section, under the config key.

Given the following configuration:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\ChromeDriverController\"\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\BuiltInServerController\"\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\DockerComposeController\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\ChromeDriverController\":\n      port: '%CHROMEDRIVER_PORT%'\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\BuiltInServerController\":\n      docroot: '%WORDPRESS_ROOT_DIR%'\n      workers: 5\n      port: '%BUILT_IN_SERVER_PORT%'\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\DockerComposeController\":\n      compose-file: 'tests/docker-compose.yml'\n      env-file: 'tests/.env'\n

Running the command will stop ChromeDriver, the built-in PHP server and Docker Compose.

"},{"location":"commands/#devrestart","title":"dev:restart","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DevRestart\"\n

This command is just a shortcut to run dev:stop and dev:start in sequence.

"},{"location":"commands/#devinfo","title":"dev:info","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DevInfo\"\n

Provides information about the local testing stack managed by the DockerComposeController, BuiltInServerController and ChromeDriverController extensions.

"},{"location":"commands/#wpdbimport","title":"wp:db:import","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DbImport\"\n

You can use WP CLI to interact with your WordPress installation, but WP CLI does not support SQLite databases in the context of the wp db import command. This command fills that gap by providing a database dump file import command that will support MySQL and SQLite databases.

"},{"location":"commands/#wpdbexport","title":"wp:db:export","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DbExport\"\n

You can use WP CLI to interact with your WordPress installation, but WP CLI does not support SQLite databases in the context of the wp db export command. This command fills that gap by providing a database dump file export command that will support MySQL and SQLite databases.

"},{"location":"commands/#chromedriverupdate","title":"chromedriver:update","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\ChromedriverUpdate\"\n

If you're using Chromedriver as a binary installed in the Composer vendor directory (vendor/bin by default), you can use this command to update it. This command will download the latest version of Chromedriver compatible with the Chrome version installed on your machine in the Composer vendor directory.

Note: if the download fails, it might be a certificate issue.

"},{"location":"commands/#generatewpunit","title":"generate:wpunit","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPUnit\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPTestCase class. The class incorporates the WordPress test case from the wordpress-develop repository and adds some utility methods to make testing easier in the context of Codeception.

The lucatume\\WPBrowser\\TestCase\\WPTestCase class is the one that should be used when writing tests for WordPress code when using the WPLoader module.

Together with the WPLoader module, the WPTestCase class provides a number of functionalities to clean up the database after each test method and to reset the global state of WordPress.

"},{"location":"commands/#every-test-method-runs-in-a-transaction","title":"Every test method runs in a transaction","text":"

Database queries running in the context of test methods of a test case extending the WPTestCase class will run in a transaction that is rolled back after the test method is run. This means that any database change happening in the context of a test method will not appear in the database while the test is running and after the test is run.

"},{"location":"commands/#generatewpajax","title":"generate:wpajax","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPAjax\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPAjaxTestCase class. This class is a version of the WPTestCase designed to test AJAX requests.

"},{"location":"commands/#generatewpcanonical","title":"generate:wpcanonical","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPCanonical\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPCanonicalTestCase class. This class is a version of the WPTestCase designed to test canonical redirects.

"},{"location":"commands/#generatewprestapi","title":"generate:wprestapi","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPRestApi\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPRestApiTestCase class. This class is a version of the WPTestCase designed to test the handling of REST API requests.

"},{"location":"commands/#generatewprestcontroller","title":"generate:wprestcontroller","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPRestController\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPRestControllerTestCase class. This class is a version of the WPTestCase designed to unit-test REST API controllers.

"},{"location":"commands/#generatewprestposttypecontroller","title":"generate:wprestposttypecontroller","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPRestPostTypeController\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPRestPostTypeControllerTestCase class. This class is a version of the WPTestCase designed to unit-test REST API controllers for post types.

"},{"location":"commands/#generatewpxml","title":"generate:wpxml","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPXML\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPXMLTestCase class. This class is a version of the WPTestCase designed to test the production of XML data.

"},{"location":"commands/#generatewpxmlrpc","title":"generate:wpxmlrpc","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPXMLRPC\"\n

Generate a test case extending the lucatume\\WPBrowser\\TestCase\\WPXMLRPCTestCase class. This class is a version of the WPTestCase designed to test the XML-RPC API.

"},{"location":"commands/#monkeycachepath","title":"monkey:cache:path","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\MonkeyCachePath\"\n

Get the path to the monkey-patching cache directory.

Use the --porcelain or -p option to get the path without any additional output.

"},{"location":"commands/#monkeycacheclear","title":"monkey:cache:clear","text":"

Enable the command with:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\MonkeyCacheClear\"\n

Clear the monkey-patching cache.

Use the --porcelain or -p option to suppress any confirmation output.

"},{"location":"custom-configuration/","title":"Custom configuration","text":""},{"location":"custom-configuration/#custom-testing-configuration","title":"Custom testing configuration","text":"

Any non default configuration is considered a custom configuration. If your project requires a tailored set up, this is the configuration for you.

"},{"location":"custom-configuration/#using-a-custom-configuration-to-run-tests","title":"Using a custom configuration to run tests","text":"

If you decide to skip the default configuration, or are working on a project that cannot use the default configuration you will be able to set up wp-browser to suit your needs using a custom configuration.

Choose \"no\", to not use the default configuration, when running the vendor/bin/codecept init wpbrowser command.

The command will set up the file structure to be able to run integration and end-to-end tests and will leverage Codeception dynamic configuration using parameters to control the testing stack using the tests/.env file.

"},{"location":"custom-configuration/#walkthrough-of-the-testsenv-file","title":"Walkthrough of the tests/.env file","text":"
  • WORDPRESS_ROOT_DIR - the path to the root WordPress installation directory. This is the directory that contains WordPress files, like wp-load.php. This path can be absolute or relative to the root project directory; e.g. vendor/wordpress (relative) or /var/www/wordpress (absolute) will work.
  • WORDPRESS_URL - the URL of the WordPress installation. This is the URL that will be used by the browser to access the WordPress installation in the context of end-to-end tests; e.g. http://localhost:8080 or https://wordpress.local.
  • WORDPRESS_DOMAIN - the domain of the WordPress installation; this value should follow the WORDPRESS_URL value. E.g. if WORDPRESS_URL is http://localhost:8080 the WORDPRESS_DOMAIN value should be localhost:8080; if WORDPRESS_URL is https://wordpress.local the WORDPRESS_DOMAIN value should be wordpress.local.
  • WORDPRESS_DB_URL - the user, password, host, and name of the database used by the tests. If the database is a MySQL database, the value should be in the form mysql://user:password@host:port/database_name. If the database is a SQLite database, the value should be in the form sqlite://path/to/database/file.
  • WORDPRESS_TABLE_PREFIX - the database table prefix used by the WordPress installation, the one served at WORDPRESS_URL. This value is usually wp_ but can be different if the WordPress installation has been configured to use a different prefix.
  • TEST_TABLE_PREFIX - the database table prefix used by the WPLoader module to install WordPress and run the tests. This value is usually test_ and should be different from the WORDPRESS_TABLE_PREFIX value.
  • WORDPRESS_ADMIN_USER - the username of the WordPress administrator user. E.g. admin.
  • WORDPRESS_ADMIN_PASSWORD - the password of the WordPress administrator user. E.g. secret!password.
  • CHROMEDRIVER_HOST - the host of the Chromedriver server. This value is usually localhost if you're running Chromedriver on the same machine as the tests. If you're running your tests using a container stack, it will be the name of the container running Chromedriver, e.g. chromedriver.
  • CHROMEDRIVER_PORT - the port of the Chromedriver server. This value is usually 9515 if you're running Chromedriver on the same machine as the tests. If you're running your tests using a container stack, it will be the port exposed by the container running Chromedriver, e.g. 4444. Note the default configuration will set this value to a random port during set up to avoid conflicts with other services running on the same machine.
"},{"location":"custom-configuration/#handling-custom-file-structures","title":"Handling custom file structures","text":"

If your site uses a customized file structure to manage WordPress, you will need to further configure the WPLoader module to correctly look for the site content. Read more about setting up WPLoader to correctly load plugins and themes from custom locations here.

"},{"location":"default-configuration/","title":"Default configuration","text":""},{"location":"default-configuration/#default-testing-configuration","title":"Default testing configuration","text":"

The recommended configuration for most projects. It allows you to get into WordPress integration and end-to-end testing quickly and easily.

"},{"location":"default-configuration/#requirements","title":"Requirements","text":"

The default configuration will set up Codeception and wp-browser to use SQLite as the database engine, PHP built-in server to serve the test site on localhost and your local version of Chrome, driven by Chromedriver, to run end-to-end tests.

As such, the default configuration has the following requirements:

  • the sqlite3 PHP extension; you can check if if's installed by running php -m | grep sqlite3 in your terminal
  • the pdo_sqlite PHP extension; you can check if if's installed by running php -m | grep pdo_sqlite in your terminal
  • PHP built-in server can work with only one thread, but it will be faster using multiple threads; multiple threads are not supported on Windows, but they are supported on WSL.
  • the Chrome browser installed on your machine
"},{"location":"default-configuration/#overview-plugin-and-theme-project","title":"Overview - plugin and theme project","text":"

If you're configuring wp-browser for a plugin or theme project, the default configuration will install WordPress in the tests/_wordpress directory and configure the installation to run using SQLite as a database engine. The SQLite Database Integration plugin) will be placed in the installation must-use plugins directory.

If your plugin or theme project requires additional plugins or theme to work, you can place them in the tests/_worpdress/wp-content/plugins and tests/_wordpress/wp-content/themes directories respectively.

When adding, or removing, plugin and themes, remember to update the WPLoader module configuration to load the correct plugins and themes in your integration tests.

On the same note, update the database dump used by the WPDb module to reflect the changes in the dump loaded in the end-to-end tests. The easiest way to update the database fixture is to load the current database dump using the wp:db:import command, manually setting up the site interacting with it and then exporting the database dump using the wp:db:export command.

You can find out about the URL of the site served by the PHP built-in web server by running the dev:info command.

"},{"location":"default-configuration/#overview-site-project","title":"Overview - site project","text":"

If you're configuring wp-browser for a site project, the default configuration will use a combination of PHP built-in web server and the SQLite Database Integration plugin to run the tests and serve your site.

The router file used by the PHP built-in web server will force the site, when served on localhost, to use SQLite as database engine leaving your existing local MySQL database untouched.

Your existing WordPress installation will be picked up as it is, with all the plugins and themes found in the contents directory.

Existing plugins and themes are not added to WPLoader module configuration by wp-browser, you have to do that manually.

Similarly, the database dump used by the WPDb module is, by default, an empty WordPress installation where no plugins and themes are active. You have to update the database dump used by the module to reflect the state of your site. You can do that by loading the current database dump using the wp:db:import command, manually setting up the site interacting with it and then exporting the database dump using the wp:db:export command.

You can find out about the URL of the site served by the PHP built-in web server by running the dev:info command.

"},{"location":"default-configuration/#when-not-to-use-the-default-configuration","title":"When not to use the default configuration","text":"

The default configuration is the recommended one for most projects, but some projects might require you to use a custom configuration to make the most out of wp-browser.

"},{"location":"default-configuration/#database-drop-in","title":"Database drop-in","text":"

The default configuration will use the SQLite Database Integration plugin to use SQLite as the database engine. This requires placing a db.php drop-in file in the WordPress content directory.

If your project already requires a db.php drop-in file, you will have to use a custom configuration.

"},{"location":"default-configuration/#multisite-with-sub-domains","title":"Multisite with sub-domains","text":"

While Chrome will handle sub-domains correctly, even on localhost, WordPress will not. If you're testing a multisite installation with sub-domains, you will have to use a custom configuration.

"},{"location":"default-configuration/#custom-site-structure","title":"Custom site structure","text":"

If your site uses a customized file structure to manage WordPress, you will need to configure wp-browser using a custom configuration. This is usually true for some site projects, and will most likely not be an issue for plugin and theme projects.

Using a custom configuration is not that difficult though: read more about using a custom configuration here.

"},{"location":"extensions/","title":"Extensions","text":"

The library provides custom Codeception extensions that can be added to the project configuration file, codeception.yml or codeception.dist.yml by default, in the extensions section.

  • BuiltInServerController
  • ChromeDriverController
  • DockerComposeController
  • IsolationSupport
  • Symlinker
  • EventDispatcherBridge
"},{"location":"migration/","title":"Migrating to newer versions","text":"

Depending on your project PHP compatibility, you have three options to choose from:

  • Your project supports PHP 7.1 to 7.4: migrate to wp-browser version 3.5
  • Your project supports PHP 8.0 or above: migrate to wp-browser version 4.0
  • You cannot, or do not want, to migrate from version 3 of wp-browser to a new version: see how you can lock your reuirements to avoid the upgrade
"},{"location":"migration/#version-35-and-40","title":"Version 3.5 and 4.0","text":"

Version 3.5 and 4.0 are the latest versions of wp-browser. Version 3.5 is a transpile of version 4 to be compatible with PHP 7.1 to 7.4 that contains, for all intents and purposes, the same facilities and systems contained in version 4 of wp-browser adapter to work on lower PHP versions and version 4 of Codeception.

Future development of wp-browser will happen on version 4 and will be transpiled to version 3.5 for back-compatibility purposes.

"},{"location":"migration/#migrate-from-version-3-to-35","title":"Migrate from version 3 to 3.5","text":"
  1. Update the required version of wp-browser in your composer.json file to 3.5:
    {\n  \"require-dev\": {\n    \"lucatume/wp-browser\": \"^3.5\"\n  }\n}\n
  2. See the changes common to version 3.5 and 4.0
"},{"location":"migration/#migrate-from-version-3-to-4","title":"Migrate from version 3 to 4","text":"
  1. Update the required version of wp-browser in your composer.json file to 4.0:
    {\n  \"require-dev\": {\n    \"lucatume/wp-browser\": \"^4.0\"\n  }\n}\n
  2. See the changes common to version 3.5 and 4.0
"},{"location":"migration/#changes-common-to-version-35-and-40","title":"Changes common to version 3.5 and 4.0","text":"
  1. Update your main Codeception configuration file (e.g. codeception.yml) to enable the new commands:

extensions:\n  commands:\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\RunOriginal\"\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\RunAll\"\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DbExport\"\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\DbImport\"\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\MonkeyCachePath\"\n    - \"lucatume\\\\WPBrowser\\\\Command\\\\MonkeyCacheClear\"\n
2. Along with the new commands, update the existing commands to use the lucatume\\WPBrowser\\Command\\ namespace:

extensions:\n  commands:\n-    - \"Codeception\\\\Command\\\\GenerateWPUnit\"\n-    - \"Codeception\\\\Command\\\\GenerateWPRestApi\"\n-    - \"Codeception\\\\Command\\\\GenerateWPRestController\"\n-    - \"Codeception\\\\Command\\\\GenerateWPRestPostTypeController\"\n-    - \"Codeception\\\\Command\\\\GenerateWPAjax\"\n-    - \"Codeception\\\\Command\\\\GenerateWPCanonical\"\n-    - \"Codeception\\\\Command\\\\GenerateWPXMLRPC\"\n+    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPUnit\"\n+    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPRestApi\"\n+    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPRestController\"\n+    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPRestPostTypeController\"\n+    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPAjax\"\n+    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPCanonical\"\n+    - \"lucatume\\\\WPBrowser\\\\Command\\\\GenerateWPXMLRPC\"\n
3. If your test code is loading deprecated functions, arguments, classes, files, or hooks, you need to update your test code to let the test case know using the setExpectedDeprecated method:
<?php\n\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTestUsingDeprecatedCode extends WPTestCase {\n    public function test_deprecatd_function() {\n        // add_filter( 'deprecated_function_trigger_error', '__return_false' );\n        $this->setExpectedDeprecated( 'my_deprecated_function' );\n        my_deprecated_function();\n    }\n\n    public function test_deprecated_class(){\n        // add_filter( 'deprecated_class_trigger_error', '__return_false' );\n        $this->setExpectedDeprecated( 'MyDeprecatedClass' );\n        new MyDeprecatedClass();\n    }\n\n    public function test_deprecated_file(){\n        // add_filter( 'deprecated_file_trigger_error', '__return_false' );\n        $this->setExpectedDeprecated( '/path/to/my_deprecated_file.php' );\n        require_once 'my_deprecated_file.php';\n    }\n\n    public function test_deprecated_hook(){\n        // add_filter( 'deprecated_hook_trigger_error', '__return_false' );\n        $this->setExpectedDeprecated( 'my_deprecated_hook' );\n        do_action( 'my_deprecated_hook' );\n    }\n}\n
Previously, your code could just filter the deprecated_function_trigger_error, deprecated_argument_trigger_error, deprecated_class_trigger_error, deprecated_file_trigger_error, and deprecated_hook_trigger_error, hooks to return false to tolerate the deprecation notices in tests. 4. If your test code is directly modifying properties like $expected_deprecated or $expected_doing_it_wrong directly, you need to update your test code to use the setExpectedDeprecated and setExpectedIncorrectUsage methods:
<?php\n\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\nclass MyTestUsingDeprecatedCode extends WPTestCase {\n    public function test_deprecated_function() {\n        // $this->expected_deprecated[] = 'my_deprecated_function';\n        $this->setExpectedDeprecated( 'my_deprecated_function' );\n        my_deprecated_function();\n    }\n\n    public function test_doing_it_wrong(){\n        // $this->expected_doing_it_wrong[] = 'my_doing_it_wrong';\n        $this->setExpectedIncorrectUsage( 'my_doing_it_wrong' );\n        my_doing_it_wrong();\n    }\n}\n
5. If your test code is knowingly triggering doing-it-wrong notices, you need to update your test code to let the test case know using the setExpectedIncorrectUsage method:
<?php\n\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\nclass MyTestUsingDoingItWrongTest extends WPTestCase {\n    public function test_it_can_use_doing_it_wrong() {\n        $this->setExpectedIncorrectUsage( 'my_doing_it_wrong' );\n        my_doing_it_wrong();\n    }\n}\n
Previously, your code could just filter the doing_it_wrong_trigger_error hook to return false to tolerate the doing-it-wrong notices in tests. 6. Some assertion methods have, in more recent versions of the PHPUnit core suite, adopted stricter type checks when it comes to comparison. E.g., the assertEqualFields will now check the object to check the fields on is actually an object. Depending on how loose your use of assertions was before, you might have to update your work to make it pass the stricter checks:
<?php\n\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\n class MyTestUsingAssertEqualFields extends WPTestCase {\n      public function test_it_can_use_assert_equal_fields() {\n         // Cast the array to an object explicitly.\n         $this->assertEqualFields( (object) [ 'a' => 1 ], [ 'a' => 1 ] );\n      }\n }\n
7. Other updates to the Core PHPUnit test case will report use of deprecated functions more promptly; if your code is using deprecated functions that might have escaped previous versions of wp-browser, you will need to update them. 8. If you're using the @runInSeparateProcess annotation for tests in your suite, you will need to enable the IsolationSupport extension in your suite configuration file:

actor: MySuiteTester\nbootstrap: _bootstrap.php\nextensions:\nenabled:\n   - \"lucatume\\\\WPBrowser\\\\Extension\\\\IsolationSupport\"\nmodules: # The rest of the module configuration ...\n

Alternatively, you can enable the extension in the Codeception main configuration file (e.g. codeception.yml).

Read more about the extension in the Isolation Support extension documentation. 9. Global space cleanup between test is more thorough in more recent versions of the Core PHPUnit test suite. Due to this you might see failures in tests that were passing in previous versions due to a \"leaking\" global state. Examples of this might be nonces being set by previous tests and not being reset. Update your tests to explicitly set all the global stat variables you require for the test to run.

"},{"location":"migration/#staying-on-version-3-lower-than-35","title":"Staying on version 3, lower than 3.5","text":"

Update your composer.json file to lock the required version of wp-browser to a version less than 3.5:

{\n  \"require-dev\": {\n    \"lucatume/wp-browser\": \"<3.5\"\n  }\n}\n
"},{"location":"troubleshooting/","title":"Troubleshooting","text":""},{"location":"troubleshooting/#troubleshooting-common-issues","title":"Troubleshooting common issues","text":""},{"location":"troubleshooting/#downloads-fail-in-windows","title":"Downloads fail in Windows","text":"

If you're using code or commands, e.g. the chromedriver:update one, that download files and those keep failing with a message like the following:

File ... download failed: SSL certificate problem: unable to get local issuer certificate\n

It's likely the issue originates from PHP not having access to the system certificate store.

You can fix this by downloading the certificates file and setting the curl.cainfo and openssl.cafile PHP configuration options to point to it:

curl.cainfo = \"C:\\path\\to\\cacert.pem\"\nopenssl.cafile = \"C:\\path\\to\\cacert.pem\"\n
"},{"location":"extensions/BuiltInServerController/","title":"PHP Built-in Server Controller","text":"

This extension will start and stop the PHP built-in web server before and after the tests run.

"},{"location":"extensions/BuiltInServerController/#configuration","title":"Configuration","text":"

The extension can be configured with the following parameters:

  • required
    • docroot - the document root to use for the PHP Built-in server; it can be either an absolute path or a path relative to the Codeception root directory. Note the lowercase r in the parameter name.
  • optional
    • suites - an array of Codeception suites to run the server for; if not set the server will be started for all the suites.
    • port - the port to use for the PHP Built-in server, if not set the server will use port 2389.
    • workers - the number of workers to use for the PHP Built-in server, if not set the server will use 5 workers. This is the equivalent of the PHP_CLI_SERVER_WORKERS environment variable.

Note: if you run PHP built-in server on Windows, the workers parameter will be ignored and the server will always run with a single worker. This limit is not present in WSL.

"},{"location":"extensions/BuiltInServerController/#configuration-examples","title":"Configuration Examples","text":"

Example configuration starting the server for all suites:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\BuiltInServerController\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\BuiltInServerController\":\n      docroot: /var/www/html\n      workers: 5\n

The extension can access environment variables defined in the tests configuration file:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\BuiltInServerController\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\BuiltInServerController\":\n      suites:\n        - EndToEnd\n        - WebApp\n      docroot: '%WORDPRESS_ROOT_DIR%'\n      port: '%BUILT_IN_SERVER_PORT%'\n      workers: '%BUILT_IN_SERVER_WORKERS%'\n
"},{"location":"extensions/BuiltInServerController/#this-is-a-service-extension","title":"This is a service extension","text":"

This is a service extension that will be started and stopped by the dev:start and dev:stop commands.

"},{"location":"extensions/ChromeDriverController/","title":"ChromeDriver Controller","text":"

This extension will start and stop the ChromeDriver before and after the tests are run.

"},{"location":"extensions/ChromeDriverController/#configuration","title":"Configuration","text":"

The extension can be configured with the following parameters:

  • optional
    • suites - an array of Codeception suites to run the server for; if not set the server will be started for all the suites.
    • port - the port to use for the ChromeDriver, if not set the server will use port 9515.
    • binary - the path to the ChromeDriver binary, if not set the server will use the chromedriver binary in the Composer bin directory.
"},{"location":"extensions/ChromeDriverController/#configuration-examples","title":"Configuration Examples","text":"

Example configuration starting the server for all suites:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\ChromeDriverController\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\ChromeDriverController\":\n      port: 4444\n      binary: /usr/local/bin/chromedriver\n

The extension can access environment variables defined in the tests configuration file:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\ChromeDriverController\"\n  config:\n    suites:\n      - EndToEnd\n      - WebApp\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\ChromeDriverController\":\n      port: '%CHROMEDRIVER_PORT%'\n      binary: '%CHROMEDRIVER_BINARY%'\n

You can use the chromedriver:update command to download the latest version of ChromeDriver compatible with your Chrome browser version and place it in the Composer bin directory.

"},{"location":"extensions/ChromeDriverController/#this-is-a-service-extension","title":"This is a service extension","text":"

This is a service extension that will be started and stopped by the dev:start and dev:stop commands.

"},{"location":"extensions/DockerComposeController/","title":"Docker Compose Controller","text":"

This extension will start and stop a docker compose stack before and after the tests are run.

"},{"location":"extensions/DockerComposeController/#configuration","title":"Configuration","text":"

The extension can be configured with the following parameters:

  • required
    • compose-file - the path to the docker compose file to use; it can be either an absolute path or a path relative to the Codeception root directory.
  • optional
    • env-file- the path to the environment file to use; it can be either an absolute path or a path.
"},{"location":"extensions/DockerComposeController/#configuration-examples","title":"Configuration Examples","text":"

Example configuration starting the server for all suites:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\DockerComposeController\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\DockerComposeController\":\n      compose-file: /var/www/html/docker-compose.yml\n      env-file: /var/www/html/.env\n

The extension can access environment variables defined in the tests configuration file:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\DockerComposeController\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\DockerComposeController\":\n      compose-file: '%DOCKER_COMPOSE_FILE%'\n      env-file: '%DOCKER_COMPOSE_ENV_FILE%'\n
"},{"location":"extensions/DockerComposeController/#this-is-a-service-extension","title":"This is a service extension","text":"

This is a service extension that will be started and stopped by the dev:start and wp:dev-stop commands.

"},{"location":"extensions/EventDispatcherBridge/","title":"Event Dispatcher Bridge","text":"

This extension connects the event dispatcher system provided by Codeception, and normally available only through the use of custom extensions, to make it available through calls to the lucatume\\WPBrowser\\Events\\Dispatcher class API.

If not using this extension, then the only way to subscribe to events dispatched by Codeception is to use custom extensions.

"},{"location":"extensions/EventDispatcherBridge/#configuration","title":"Configuration","text":"

The extension does not require configuration, it just needs to be enabled in the Codeception configuration file:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\EventDispatcherBridge\"\n
"},{"location":"extensions/EventDispatcherBridge/#usage","title":"Usage","text":"

The extension will automatically hook into the event dispatcher system provided by Codeception, normally available only through the use of custom extensions, and inject user-defined event listeners in it.

Once the extension is enabled, you can use the lucatume\\WPBrowser\\Events\\Dispatcher class to subscribe to Codeception events. This is typically be done in either the global bootstrap file, or in a suite bootstrap file.

You can subscribe to the following events dispatched by Codeception in either the global bootstrap file (usually tests/_bootstrap.php), or in a suite bootstrap file (usually tests/<suite>/_bootstrap.php):

  • Codeception\\Events::SUITE_BEFORE
  • Codeception\\Events::SUITE_AFTER
  • CodeceptionventsEvents::TEST_START
  • CodeceptionventsEvents::TEST_BEFORE
  • CodeceptionventsEvents::STEP_BEFORE
  • CodeceptionventsEvents::STEP_AFTER
  • CodeceptionventsEvents::TEST_FAIL
  • CodeceptionventsEvents::TEST_ERROR
  • CodeceptionventsEvents::TEST_PARSED
  • CodeceptionventsEvents::TEST_INCOMPLETE
  • CodeceptionventsEvents::TEST_SKIPPED
  • CodeceptionventsEvents::TEST_WARNING
  • CodeceptionventsEvents::TEST_USELESS
  • CodeceptionventsEvents::TEST_SUCCESS
  • CodeceptionventsEvents::TEST_AFTER
  • CodeceptionventsEvents::TEST_END
  • CodeceptionventsEvents::TEST_FAIL_PRINT
  • CodeceptionventsEvents::RESULT_PRINT_AFTER

Due to order-of-operations, the earliest Codeception dispatched Event you can subscribe to is the SUITE_BEFORE one. To subscribe to the following earlier events, you must implement an extension following the custom extension approach:

  • Codeception\\Events::MODULE_INIT
  • Codeception\\Events::SUITE_INIT

The Dispatcher API documentation provides more details about the events dispatched by Codeception and wp-browser and examples on how to subscribe to them.

"},{"location":"extensions/EventDispatcherBridge/#usage-examples","title":"Usage Examples","text":"

In the global bootstrap file (usually tests/_bootstrap.php), or the suite bootstrap file (usually tests/<suite>/_bootstrap.php), subscribe to the Codeception events by providing a callback function that will accept different parameters depending on the event being dispatched:

<?php\n\nuse Codeception\\Events;\nuse Codeception\\Event\\SuiteEvent\nuse Codeception\\Event\\TestEvent;\nuse Codeception\\Event\\StepEvent;\nuse Codeception\\Event\\PrintResultEvent;\nuse lucatume\\WPBrowser\\Events\\Dispatcher;\n\nDispatcher::addListener(Events::SUITE_BEFORE, function (SuiteEvent $suiteEvent) {\n    codecept_debug('Running on SUITE BEFORE');\n});\n\nDispatcher::addListener(Events::SUITE_AFTER, function (SuiteEvent $suiteEvent) {\n    codecept_debug('Running on SUITE AFTER');\n});\n\nDispatcher::addListener(Events::TEST_START, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST START');\n});\n\nDispatcher::addListener(Events::TEST_BEFORE, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST BEFORE');\n});\n\nDispatcher::addListener(Events::STEP_BEFORE, function (StepEvent $stepEvent) {\n    codecept_debug('Running on STEP BEFORE');\n});\n\nDispatcher::addListener(Events::STEP_AFTER, function (StepEvent $stepEvent) {\n    codecept_debug('Running on STEP AFTER');\n});\n\nDispatcher::addListener(Events::TEST_FAIL, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST FAIL');\n});\n\nDispatcher::addListener(Events::TEST_ERROR, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST ERROR');\n});\n\nDispatcher::addListener(Events::TEST_PARSED, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST PARSED');\n});\n\nDispatcher::addListener(Events::TEST_INCOMPLETE, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST INCOMPLETE');\n});\n\nDispatcher::addListener(Events::TEST_SKIPPED, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST SKIPPED');\n});\n\nDispatcher::addListener(Events::TEST_WARNING, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST WARNING');\n});\n\nDispatcher::addListener(Events::TEST_USELESS, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST USELESS');\n});\n\nDispatcher::addListener(Events::TEST_SUCCESS, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST SUCCESS');\n});\n\nDispatcher::addListener(Events::TEST_AFTER, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST AFTER');\n});\n\nDispatcher::addListener(Events::TEST_END, function (TestEvent $testEvent) {\n    codecept_debug('Running on TEST END');\n});\n\nDispatcher::addListener(Events::TEST_FAIL_PRINT, function (PrintResultEvent $printResultEvent) {\n    codecept_debug('Running on TEST FAIL PRINT');\n});\n\nDispatcher::addListener(Events::RESULT_PRINT_AFTER, function (PrintResultEvent $printResultEvent) {\n    codecept_debug('Running on RESULT PRINT AFTER');\n});\n

Read more about the Dispatcher API here.

"},{"location":"extensions/IsolationSupport/","title":"Isolation Support","text":"

This extension provides support for the PHPUnit annotations @runInSeparateProcess and @runTestsInSeparateProcesses, and the PHPUnit attributes (PHPUnit 10+) #[RunInSeparateProcess] and #[RunTestsInSeparateProcesses]. You can read more about these annotations and attributes in the PHPUnit documentation about test isolation.

Codeception does not natively support these annotations and attributes, this extension provides support for them.

"},{"location":"extensions/IsolationSupport/#configuration","title":"Configuration","text":"

You can enable the extension in the Codeception configuration file:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\IsolationSupport\"\n

In your tests, you can use the annotations or attributes as you would in a PHPUnit test:

<?php\n\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass IsolationExampleTest extends WPTestCase {\n    /**\n     * @runInSeparateProcess\n     */\n    public function test_in_admin_context() {\n        define('WP_ADMIN', true);\n\n        $this->assertTrue(is_admin());\n    }\n\n    #[RunTestsInSeparateProcesses]\n    public function test_in_admin_context_with_attribute() {\n        define('WP_ADMIN', true);\n\n        $this->assertTrue(is_admin());\n    }\n\n    public function test_constant_is_not_set() {\n        $this->assertFalse(defined('WP_ADMIN'));\n    }\n}\n\n#[RunTestsInSeparateProcesses]\nclass RunAllTestsInSeparateProcesses extends WPTestCase {\n    public function test_one() {\n        definen('TEST_CONST', 'one');\n\n        $this->assertEquals('one', TEST_CONST);\n    }\n\n    public function test_two() {\n        definen('TEST_CONST', 'two');\n\n        $this->assertEquals('two', TEST_CONST);\n    }\n}\n

Previous versions of the test isolation support required the @backupGlobals disabled annotation to be used when running tests in isolation. This is no longer required.

Isolation support is based around monkey-patching the file at runtime. Look into the monkey:cache:clear and monkey:cache:path commands to manage the monkey-patching cache.

"},{"location":"extensions/Symlinker/","title":"Symlinker","text":"

This extension will symlink the plugins and themes specified in the plugins and themes configuration parameters to the WordPress installation plugins and themes directories, respectively.

The plugins and themes will be symlinked before each suite, and removed after each suite.

"},{"location":"extensions/Symlinker/#configuration","title":"Configuration","text":"

The extension can be configured with the following parameters:

  • required
    • wpRootFolder - the relative (to the current working directory) or absolute path to the WordPress installation root folder, the directory that contains the wp-load.php file.
  • optional
    • cleanupAfterSuite - default false, a boolean value to indicate if the symlinks created by the extension sshould be removed after the suite ran.
    • plugins- a list of plugin directories to symlink to the WordPress installation plugins directory, if not set the plugin symlinking will be skipped.
    • themes- a list of theme directories to symlink to the WordPress installation themes directory, if not set the theme symlinking will be skipped.
"},{"location":"extensions/Symlinker/#configuration-examples","title":"Configuration Examples","text":"

Example configuration symbolically linking the plugins and themes to the WordPress installation plugins and themes directories:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\Symlinker\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\Symlinker\":\n      wpRootFolder: /var/www/html\n      plugins:\n        - '.' # Relative path, the current working directory.\n        - /home/plugins/plugin-1 # Absolute path to a plugin directory.\n        - vendor/acme/plugin-2 # Relative path to a plugin directory.\n      themes:\n        - /home/theme-1 # Absolute path to a theme directory.\n        - vendor/acme/theme-2 # Relative path to a theme directory.\n

The extension can access environment variables defined in the tests configuration file:

extensions:\n  enabled:\n    - \"lucatume\\\\WPBrowser\\\\Extension\\\\Symlinker\"\n  config:\n    \"lucatume\\\\WPBrowser\\\\Extension\\\\Symlinker\":\n      wpRootFolder: '%WP_ROOT_FOLDER%'\n      plugins:\n        - '%PLUGIN_STORAGE%/plugin-1'\n        - '%PLUGIN_STORAGE%/plugin-2'\n      themes:\n        - '%THEME_STORAGE%/theme-1'\n        - '%THEME_STORAGE%/theme-2'\n
"},{"location":"modules/AirplaneMode/","title":"Airplane Mode","text":""},{"location":"modules/AirplaneMode/#airplanemode-module","title":"AirplaneMode module","text":"

This module allows you to easily put the website under test in \"airplane mode\", preventing it from making any network requests.

The module uses the norcross/airplane-mode plugin to add or remove it from the website must-use plugins directory when activated.

This module should be used together with the WPWebDriver or WPBrowser modules.

"},{"location":"modules/AirplaneMode/#configuration","title":"Configuration","text":"
  • muPluginsDir - required; the path to the WordPress must-use plugins directory.
  • symlink - whether to symlink the plugin or copy it. By default, the plugin is copied in the must-use plugins directory and symlink is set to false. If you're not using containers, that will ignore symlinked plugins, you can set symlink to true to symlink the plugin in the must-use plugins directory. Symbolic linking is faster and uses less disk space than copying the plugin.

Example configuration to symlink the plugin in the muPluginsDir directory before the tests:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\AirplaneMode:\n      muPluginsDir: 'var/wordpress/wp-content/mu-plugins'\n      symlink: true\n

Example configuration to copy the plugin in the muPluginsDir directory before the tests:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\AirplaneMode:\n      muPluginsDir: 'var/wordpress/wp-content/mu-plugins'\n      symlink: false\n

The module will either symlink or copy the plugin in the muPluginsDir directory, depending on the symlink configuration parameter before the test suite runs, and will remove it after the test suite has run.

"},{"location":"modules/WPBrowser/","title":"WPBrowser","text":""},{"location":"modules/WPBrowser/#wpbrowser-module","title":"WPBrowser module","text":"

Browse and test the site HTML with a fast browser without Javascript support.

This module trades the WPWebDriver module Javascript support for speed and stability. It is a good choice for testing sites that don't use Javascript or to make assertions that do not require Javascript support like:

  • testing HTTP return codes
  • testing HTML structure
  • testing JSON and XML responses from APIs

This module is used together with the WPDb module and the WPFilesystem module to control the site state, the database, and the site file structure.

This module is an extension of the Codeception PHPBrowser module, you can reference to the Codeception module documentation for more information on the module configuration and usage.

This module should be with Cest and Cept test cases.

"},{"location":"modules/WPBrowser/#configuration","title":"Configuration","text":"
  • url - required; the start URL of your WordPress project.
  • adminUsername - required; the site administrator username to use in actions like loginAsAdmin.
  • adminPassword - required; the site administrator password to use in actions like loginAsAdmin.
  • adminPath - the path to the WordPress admin directory; defaults to /wp-admin.

More Guzzle request options are available like:

headers - default headers are set before each test. cookies - default cookies are set before each test. auth - default authentication to be set before each test.

... and more.

The following is an example of the module configuration to run tests on thehttp://localhost:8080 site:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPBrowser:\n      url: 'http://localhost:8080'\n      adminUsername: 'admin'\n      adminPassword: 'password'\n      adminPath: '/wp-admin'\n      headers:\n        X_WPBROWSER_REQUEST: 1\n        X_TEST_REQUEST: 1\n        X_APM_REQUEST: 1\n

The following configuration uses dynamic configuration parameters to set the module configuration:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPBrowser:\n      url: '%WORDPRESS_URL%'\n      adminUsername: '%WORDPRESS_ADMIN_USER%'\n      adminPassword: '%WORDPRESS_ADMIN_PASSWORD%'\n      adminPath: '/wp-admin'\n      headers:\n        X_WPBROWSER_REQUEST: 1\n        X_TEST_REQUEST: 1\n        X_APM_REQUEST: 1\n
"},{"location":"modules/WPBrowser/#methods","title":"Methods","text":"

The module provides the following methods:

"},{"location":"modules/WPBrowser/#activateplugin","title":"activatePlugin","text":"

Signature: activatePlugin(array|string $pluginSlug) : void

In the plugin administration screen activates a plugin clicking the \"Activate\" link.

The method will not handle authentication to the admin area.

<?php\n// Activate a plugin.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->activatePlugin('hello-dolly');\n// Activate a list of plugins.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->activatePlugin(['hello-dolly','another-plugin']);\n
"},{"location":"modules/WPBrowser/#activatetheme","title":"activateTheme","text":"

Signature: activateTheme(string $slug) : void

Activates a theme.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPBrowser/#ameditingpostwithid","title":"amEditingPostWithId","text":"

Signature: amEditingPostWithId(int $id) : void

Go to the admin page to edit the post with the specified ID.

The method will not handle authentication the admin area.

<?php\n$I->loginAsAdmin();\n$postId = $I->havePostInDatabase();\n$I->amEditingPostWithId($postId);\n$I->fillField('post_title', 'Post title');\n
"},{"location":"modules/WPBrowser/#ameditinguserwithid","title":"amEditingUserWithId","text":"

Signature: amEditingUserWithId(int $id) : void

Go to the admin page to edit the user with the specified ID.

The method will not handle authentication the admin area.

<?php\n$I->loginAsAdmin();\n$userId = $I->haveUserInDatabase('luca', 'editor');\n$I->amEditingUserWithId($userId);\n$I->fillField('email', 'new@example.net');\n
"},{"location":"modules/WPBrowser/#amhttpauthenticated","title":"amHttpAuthenticated","text":"

Signature: amHttpAuthenticated($username, $password) : void

"},{"location":"modules/WPBrowser/#amonadminajaxpage","title":"amOnAdminAjaxPage","text":"

Signature: amOnAdminAjaxPage([array|string|null $queryVars]) : void

Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.

The method will not handle authentication, nonces or authorization.

<?php\n$I->amOnAdminAjaxPage(['action' => 'my-action', 'data' => ['id' => 23], 'nonce' => $nonce]);\n
"},{"location":"modules/WPBrowser/#amonadminpage","title":"amOnAdminPage","text":"

Signature: amOnAdminPage(string $page) : void

Go to a page in the admininstration area of the site.

This method will not handle authentication to the administration area.

<?php\n$I->loginAs('user', 'password');\n// Go to the plugins management screen.\n$I->amOnAdminPage('/plugins.php');\n
"},{"location":"modules/WPBrowser/#amoncronpage","title":"amOnCronPage","text":"

Signature: amOnCronPage([array|string|null $queryVars]) : void

Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

<?php\n// Triggers the cron job with an optional query argument.\n$I->amOnCronPage('/?some-query-var=some-value');\n
"},{"location":"modules/WPBrowser/#amonpage","title":"amOnPage","text":"

Signature: amOnPage(string $page) : void

"},{"location":"modules/WPBrowser/#amonpagespage","title":"amOnPagesPage","text":"

Signature: amOnPagesPage() : void

Go the \"Pages\" administration screen.

The method will not handle authentication.

<?php\n$I->loginAsAdmin();\n$I->amOnPagesPage();\n$I->see('Add New');\n
"},{"location":"modules/WPBrowser/#amonpluginspage","title":"amOnPluginsPage","text":"

Signature: amOnPluginsPage() : void

Go to the plugins administration screen.

The method will not handle authentication.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->activatePlugin('hello-dolly');\n
"},{"location":"modules/WPBrowser/#amonsubdomain","title":"amOnSubdomain","text":"

Signature: amOnSubdomain($subdomain) : void

"},{"location":"modules/WPBrowser/#amonthemespage","title":"amOnThemesPage","text":"

Signature: amOnThemesPage() : void

Moves to the themes administration page.

"},{"location":"modules/WPBrowser/#amonurl","title":"amOnUrl","text":"

Signature: amOnUrl($url) : void

"},{"location":"modules/WPBrowser/#attachfile","title":"attachFile","text":"

Signature: attachFile($field, string $filename) : void

"},{"location":"modules/WPBrowser/#checkoption","title":"checkOption","text":"

Signature: checkOption($option) : void

"},{"location":"modules/WPBrowser/#click","title":"click","text":"

Signature: click($link, [$context]) : void

"},{"location":"modules/WPBrowser/#deactivateplugin","title":"deactivatePlugin","text":"

Signature: deactivatePlugin(array|string $pluginSlug) : void

In the plugin administration screen deactivate a plugin clicking the \"Deactivate\" link.

The method will not handle authentication and navigation to the plugins administration page.

<?php\n// Deactivate one plugin.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->deactivatePlugin('hello-dolly');\n// Deactivate a list of plugins.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->deactivatePlugin(['hello-dolly', 'my-plugin']);\n
"},{"location":"modules/WPBrowser/#deleteheader","title":"deleteHeader","text":"

Signature: deleteHeader(string $name) : void

Deletes the header with the passed name. Subsequent requests will not have the deleted header in its request.

Example:

<?php\n$I->haveHttpHeader('X-Requested-With', 'Codeception');\n$I->amOnPage('test-headers.php');\n// ...\n$I->deleteHeader('X-Requested-With');\n$I->amOnPage('some-other-page.php');\n

"},{"location":"modules/WPBrowser/#dontsee","title":"dontSee","text":"

Signature: dontSee(string $text, [$selector]) : void

"},{"location":"modules/WPBrowser/#dontseecheckboxischecked","title":"dontSeeCheckboxIsChecked","text":"

Signature: dontSeeCheckboxIsChecked($checkbox) : void

"},{"location":"modules/WPBrowser/#dontseecookie","title":"dontSeeCookie","text":"

Signature: dontSeeCookie($cookie, [$params]) : void

"},{"location":"modules/WPBrowser/#dontseecurrenturlequals","title":"dontSeeCurrentUrlEquals","text":"

Signature: dontSeeCurrentUrlEquals(string $uri) : void

"},{"location":"modules/WPBrowser/#dontseecurrenturlmatches","title":"dontSeeCurrentUrlMatches","text":"

Signature: dontSeeCurrentUrlMatches(string $uri) : void

"},{"location":"modules/WPBrowser/#dontseeelement","title":"dontSeeElement","text":"

Signature: dontSeeElement($selector, [array $attributes]) : void

"},{"location":"modules/WPBrowser/#dontseeincurrenturl","title":"dontSeeInCurrentUrl","text":"

Signature: dontSeeInCurrentUrl(string $uri) : void

"},{"location":"modules/WPBrowser/#dontseeinfield","title":"dontSeeInField","text":"

Signature: dontSeeInField($field, $value) : void

"},{"location":"modules/WPBrowser/#dontseeinformfields","title":"dontSeeInFormFields","text":"

Signature: dontSeeInFormFields($formSelector, array $params) : void

"},{"location":"modules/WPBrowser/#dontseeinsource","title":"dontSeeInSource","text":"

Signature: dontSeeInSource(string $raw) : void

"},{"location":"modules/WPBrowser/#dontseeintitle","title":"dontSeeInTitle","text":"

Signature: dontSeeInTitle($title) : void

"},{"location":"modules/WPBrowser/#dontseelink","title":"dontSeeLink","text":"

Signature: dontSeeLink(string $text, [string $url]) : void

"},{"location":"modules/WPBrowser/#dontseeoptionisselected","title":"dontSeeOptionIsSelected","text":"

Signature: dontSeeOptionIsSelected($selector, $optionText) : void

"},{"location":"modules/WPBrowser/#dontseeplugininstalled","title":"dontSeePluginInstalled","text":"

Signature: dontSeePluginInstalled(string $pluginSlug) : void

Assert a plugin is not installed in the plugins administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->dontSeePluginInstalled('my-plugin');\n
"},{"location":"modules/WPBrowser/#dontseeresponsecodeis","title":"dontSeeResponseCodeIs","text":"

Signature: dontSeeResponseCodeIs(int $code) : void

Checks that response code is equal to value provided.

<?php\n$I->dontSeeResponseCodeIs(200);\n\n// recommended \\Codeception\\Util\\HttpCode\n$I->dontSeeResponseCodeIs(\\Codeception\\Util\\HttpCode::OK);\n
"},{"location":"modules/WPBrowser/#executeinguzzle","title":"executeInGuzzle","text":"

Signature: executeInGuzzle(Closure $function) : void

Low-level API method. If Codeception commands are not enough, use Guzzle HTTP Client methods directly

Example:

<?php\n$I->executeInGuzzle(function (\\GuzzleHttp\\Client $client) {\n     $client->get('/get', ['query' => ['foo' => 'bar']]);\n});\n

It is not recommended to use this command on a regular basis. If Codeception lacks important Guzzle Client methods, implement them and submit patches.

"},{"location":"modules/WPBrowser/#fillfield","title":"fillField","text":"

Signature: fillField($field, $value) : void

"},{"location":"modules/WPBrowser/#followredirect","title":"followRedirect","text":"

Signature: followRedirect() : void

Follow pending redirect if there is one.

<?php\n$I->followRedirect();\n
"},{"location":"modules/WPBrowser/#grabactivetheme","title":"grabActiveTheme","text":"

Signature: grabActiveTheme() : ?string

Returns the slug of the currently active themes.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPBrowser/#grabattributefrom","title":"grabAttributeFrom","text":"

Signature: grabAttributeFrom($cssOrXpath, string $attribute) : mixed

"},{"location":"modules/WPBrowser/#grabavailablethemes","title":"grabAvailableThemes","text":"

Signature: grabAvailableThemes([string $classes]) : array

Returns the list of available themes.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPBrowser/#grabcookie","title":"grabCookie","text":"

Signature: grabCookie(string $cookie, [array $params]) : mixed

"},{"location":"modules/WPBrowser/#grabcookieswithpattern","title":"grabCookiesWithPattern","text":"

Signature: grabCookiesWithPattern(string $cookiePattern) : ?array

Returns all the cookies whose name matches a regex pattern.

<?php\n$I->loginAs('customer','password');\n$I->amOnPage('/shop');\n$cartCookies = $I->grabCookiesWithPattern(\"#^shop_cart\\\\.*#\");\n
"},{"location":"modules/WPBrowser/#grabfromcurrenturl","title":"grabFromCurrentUrl","text":"

Signature: grabFromCurrentUrl([?string $uri]) : mixed

"},{"location":"modules/WPBrowser/#grabmultiple","title":"grabMultiple","text":"

Signature: grabMultiple($cssOrXpath, [?string $attribute]) : array

"},{"location":"modules/WPBrowser/#grabpagesource","title":"grabPageSource","text":"

Signature: grabPageSource() : string

Grabs current page source code.

"},{"location":"modules/WPBrowser/#grabtextfrom","title":"grabTextFrom","text":"

Signature: grabTextFrom($cssOrXPathOrRegex) : mixed

"},{"location":"modules/WPBrowser/#grabvaluefrom","title":"grabValueFrom","text":"

Signature: grabValueFrom($field) : mixed

"},{"location":"modules/WPBrowser/#grabwordpresstestcookie","title":"grabWordPressTestCookie","text":"

Signature: grabWordPressTestCookie([?string $name]) : ?Symfony\\Component\\BrowserKit\\Cookie

Returns WordPress default test cookie object if present.

<?php\n// Grab the default WordPress test cookie.\n$wpTestCookie = $I->grabWordPressTestCookie();\n// Grab a customized version of the test cookie.\n$myTestCookie = $I->grabWordPressTestCookie('my_test_cookie');\n
"},{"location":"modules/WPBrowser/#havehttpheader","title":"haveHttpHeader","text":"

Signature: haveHttpHeader(string $name, string $value) : void

Sets the HTTP header to the passed value - which is used on subsequent HTTP requests through PhpBrowser.

Example:

<?php\n$I->haveHttpHeader('X-Requested-With', 'Codeception');\n$I->amOnPage('test-headers.php');\n

To use special chars in Header Key use HTML Character Entities: Example: Header with underscore - 'Client_Id' should be represented as - 'Client_Id' or 'Client_Id'

<?php\n$I->haveHttpHeader('Client&#95;Id', 'Codeception');\n
"},{"location":"modules/WPBrowser/#haveserverparameter","title":"haveServerParameter","text":"

Signature: haveServerParameter(string $name, string $value) : void

Sets SERVER parameter valid for all next requests.

<?php\n$I->haveServerParameter('name', 'value');\n
"},{"location":"modules/WPBrowser/#logout","title":"logOut","text":"

Signature: logOut([string|bool $redirectTo]) : void

Navigate to the default WordPress logout page and click the logout link.

<?php\n// Log out using the `wp-login.php` form and return to the current page.\n$I->logOut(true);\n// Log out using the `wp-login.php` form and remain there.\n$I->logOut(false);\n// Log out using the `wp-login.php` form and move to another page.\n$I->logOut('/some-other-page');\n
"},{"location":"modules/WPBrowser/#loginas","title":"loginAs","text":"

Signature: loginAs(string $username, string $password) : void

Login as the specified user.

The method will not follow redirection, after the login, to any page.

<?php\n$I->loginAs('user', 'password');\n$I->amOnAdminPage('/');\n$I->see('Dashboard');\n
"},{"location":"modules/WPBrowser/#loginasadmin","title":"loginAsAdmin","text":"

Signature: loginAsAdmin() : void

Login as the administrator user using the credentials specified in the module configuration.

The method will not follow redirection, after the login, to any page.

<?php\n$I->loginAsAdmin();\n$I->amOnAdminPage('/');\n$I->see('Dashboard');\n
"},{"location":"modules/WPBrowser/#makehtmlsnapshot","title":"makeHtmlSnapshot","text":"

Signature: makeHtmlSnapshot([?string $name]) : void

"},{"location":"modules/WPBrowser/#moveback","title":"moveBack","text":"

Signature: moveBack([int $numberOfSteps]) : void

Moves back in history.

"},{"location":"modules/WPBrowser/#resetcookie","title":"resetCookie","text":"

Signature: resetCookie($cookie, [$params]) : void

"},{"location":"modules/WPBrowser/#see","title":"see","text":"

Signature: see(string $text, [$selector]) : void

"},{"location":"modules/WPBrowser/#seecheckboxischecked","title":"seeCheckboxIsChecked","text":"

Signature: seeCheckboxIsChecked($checkbox) : void

"},{"location":"modules/WPBrowser/#seecookie","title":"seeCookie","text":"

Signature: seeCookie($cookie, [$params]) : void

"},{"location":"modules/WPBrowser/#seecurrenturlequals","title":"seeCurrentUrlEquals","text":"

Signature: seeCurrentUrlEquals(string $uri) : void

"},{"location":"modules/WPBrowser/#seecurrenturlmatches","title":"seeCurrentUrlMatches","text":"

Signature: seeCurrentUrlMatches(string $uri) : void

"},{"location":"modules/WPBrowser/#seeelement","title":"seeElement","text":"

Signature: seeElement($selector, [array $attributes]) : void

"},{"location":"modules/WPBrowser/#seeerrormessage","title":"seeErrorMessage","text":"

Signature: seeErrorMessage([array|string $classes]) : void

In an administration screen look for an error admin notice.

The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

<?php\n$I->loginAsAdmin()\n$I->amOnAdminPage('/');\n$I->seeErrorMessage('.my-plugin');\n
"},{"location":"modules/WPBrowser/#seeincurrenturl","title":"seeInCurrentUrl","text":"

Signature: seeInCurrentUrl(string $uri) : void

"},{"location":"modules/WPBrowser/#seeinfield","title":"seeInField","text":"

Signature: seeInField($field, $value) : void

"},{"location":"modules/WPBrowser/#seeinformfields","title":"seeInFormFields","text":"

Signature: seeInFormFields($formSelector, array $params) : void

"},{"location":"modules/WPBrowser/#seeinsource","title":"seeInSource","text":"

Signature: seeInSource(string $raw) : void

"},{"location":"modules/WPBrowser/#seeintitle","title":"seeInTitle","text":"

Signature: seeInTitle($title) : void

"},{"location":"modules/WPBrowser/#seelink","title":"seeLink","text":"

Signature: seeLink(string $text, [?string $url]) : void

"},{"location":"modules/WPBrowser/#seemessage","title":"seeMessage","text":"

Signature: seeMessage([array|string $classes]) : void

In an administration screen look for an admin notice.

The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

<?php\n$I->loginAsAdmin()\n$I->amOnAdminPage('/');\n$I->seeMessage('.missing-api-token.my-plugin');\n
"},{"location":"modules/WPBrowser/#seenumberofelements","title":"seeNumberOfElements","text":"

Signature: seeNumberOfElements($selector, $expected) : void

"},{"location":"modules/WPBrowser/#seeoptionisselected","title":"seeOptionIsSelected","text":"

Signature: seeOptionIsSelected($selector, $optionText) : void

"},{"location":"modules/WPBrowser/#seepagenotfound","title":"seePageNotFound","text":"

Signature: seePageNotFound() : void

Asserts that current page has 404 response status code.

"},{"location":"modules/WPBrowser/#seepluginactivated","title":"seePluginActivated","text":"

Signature: seePluginActivated(string $pluginSlug) : void

Assert a plugin is activated in the plugin administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->seePluginActivated('my-plugin');\n
"},{"location":"modules/WPBrowser/#seeplugindeactivated","title":"seePluginDeactivated","text":"

Signature: seePluginDeactivated(string $pluginSlug) : void

Assert a plugin is not activated in the plugins administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->seePluginDeactivated('my-plugin');\n
"},{"location":"modules/WPBrowser/#seeplugininstalled","title":"seePluginInstalled","text":"

Signature: seePluginInstalled(string $pluginSlug) : void

Assert a plugin is installed, no matter its activation status, in the plugin administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->seePluginInstalled('my-plugin');\n
"},{"location":"modules/WPBrowser/#seeresponsecodeis","title":"seeResponseCodeIs","text":"

Signature: seeResponseCodeIs(int $code) : void

Checks that response code is equal to value provided.

<?php\n$I->seeResponseCodeIs(200);\n\n// recommended \\Codeception\\Util\\HttpCode\n$I->seeResponseCodeIs(\\Codeception\\Util\\HttpCode::OK);\n
"},{"location":"modules/WPBrowser/#seeresponsecodeisbetween","title":"seeResponseCodeIsBetween","text":"

Signature: seeResponseCodeIsBetween(int $from, int $to) : void

Checks that response code is between a certain range. Between actually means [from <= CODE <= to]

"},{"location":"modules/WPBrowser/#seeresponsecodeisclienterror","title":"seeResponseCodeIsClientError","text":"

Signature: seeResponseCodeIsClientError() : void

Checks that the response code is 4xx

"},{"location":"modules/WPBrowser/#seeresponsecodeisredirection","title":"seeResponseCodeIsRedirection","text":"

Signature: seeResponseCodeIsRedirection() : void

Checks that the response code 3xx

"},{"location":"modules/WPBrowser/#seeresponsecodeisservererror","title":"seeResponseCodeIsServerError","text":"

Signature: seeResponseCodeIsServerError() : void

Checks that the response code is 5xx

"},{"location":"modules/WPBrowser/#seeresponsecodeissuccessful","title":"seeResponseCodeIsSuccessful","text":"

Signature: seeResponseCodeIsSuccessful() : void

Checks that the response code 2xx

"},{"location":"modules/WPBrowser/#seethemeactivated","title":"seeThemeActivated","text":"

Signature: seeThemeActivated(string $slug) : void

Verifies that a theme is active.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPBrowser/#seewpdiepage","title":"seeWpDiePage","text":"

Signature: seeWpDiePage() : void

Checks that the current page is one generated by the wp_die function.

The method will try to identify the page based on the default WordPress die page HTML attributes.

<?php\n$I->loginAs('user', 'password');\n$I->amOnAdminPage('/forbidden');\n$I->seeWpDiePage();\n
"},{"location":"modules/WPBrowser/#selectoption","title":"selectOption","text":"

Signature: selectOption($select, $option) : void

"},{"location":"modules/WPBrowser/#sendajaxgetrequest","title":"sendAjaxGetRequest","text":"

Signature: sendAjaxGetRequest(string $uri, [array $params]) : void

Sends an ajax GET request with the passed parameters. See sendAjaxPostRequest()

"},{"location":"modules/WPBrowser/#sendajaxpostrequest","title":"sendAjaxPostRequest","text":"

Signature: sendAjaxPostRequest(string $uri, [array $params]) : void

Sends an ajax POST request with the passed parameters. The appropriate HTTP header is added automatically: X-Requested-With: XMLHttpRequest Example:

<?php\n$I->sendAjaxPostRequest('/add-task', ['task' => 'lorem ipsum']);\n
Some frameworks (e.g. Symfony) create field names in the form of an \"array\": <input type=\"text\" name=\"form[task]\"> In this case you need to pass the fields like this:
<?php\n$I->sendAjaxPostRequest('/add-task', ['form' => [\n    'task' => 'lorem ipsum',\n    'category' => 'miscellaneous',\n]]);\n

"},{"location":"modules/WPBrowser/#sendajaxrequest","title":"sendAjaxRequest","text":"

Signature: sendAjaxRequest(string $method, string $uri, [array $params]) : void

Sends an ajax request, using the passed HTTP method. See sendAjaxPostRequest() Example:

<?php\n$I->sendAjaxRequest('PUT', '/posts/7', ['title' => 'new title']);\n

"},{"location":"modules/WPBrowser/#setcookie","title":"setCookie","text":"

Signature: setCookie($name, $val, [$params]) : void

"},{"location":"modules/WPBrowser/#setheader","title":"setHeader","text":"

Signature: setHeader(string $name, string $value) : void

Alias to haveHttpHeader

"},{"location":"modules/WPBrowser/#setmaxredirects","title":"setMaxRedirects","text":"

Signature: setMaxRedirects(int $maxRedirects) : void

Sets the maximum number of redirects that the Client can follow.

<?php\n$I->setMaxRedirects(2);\n
"},{"location":"modules/WPBrowser/#setserverparameters","title":"setServerParameters","text":"

Signature: setServerParameters(array $params) : void

Sets SERVER parameters valid for all next requests. this will remove old ones.

<?php\n$I->setServerParameters([]);\n
"},{"location":"modules/WPBrowser/#startfollowingredirects","title":"startFollowingRedirects","text":"

Signature: startFollowingRedirects() : void

Enables automatic redirects to be followed by the client.

<?php\n$I->startFollowingRedirects();\n
"},{"location":"modules/WPBrowser/#stopfollowingredirects","title":"stopFollowingRedirects","text":"

Signature: stopFollowingRedirects() : void

Prevents automatic redirects to be followed by the client.

<?php\n$I->stopFollowingRedirects();\n
"},{"location":"modules/WPBrowser/#submitform","title":"submitForm","text":"

Signature: submitForm($selector, array $params, [?string $button]) : void

"},{"location":"modules/WPBrowser/#switchtoiframe","title":"switchToIframe","text":"

Signature: switchToIframe(string $name) : void

Switch to iframe or frame on the page.

Example:

<iframe name=\"another_frame\" src=\"http://example.com\">\n

<?php\n# switch to iframe\n$I->switchToIframe(\"another_frame\");\n
"},{"location":"modules/WPBrowser/#uncheckoption","title":"uncheckOption","text":"

Signature: uncheckOption($option) : void

Read more in Codeception documentation.

"},{"location":"modules/WPCLI/","title":"WPCLI","text":""},{"location":"modules/WPCLI/#wpcli-module","title":"WPCLI module","text":"

Use WP-CLI to interact with the WordPress installation under test and issue commands.

This module is used in the context of end-to-end testing, together with, or as a replacement for the WPDb module to manipulate the database and the WPFilesystem module to manipulate the site file structure.

This module should be with Cest and Cept test cases.

"},{"location":"modules/WPCLI/#configuration","title":"Configuration","text":"
  • path - required; the path to the WordPress installation under test. This can be a relative path to the codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation directory is the directory that contains the wp-load.php file.
  • url - the URL of the WordPress installation under test. Equivalent to the --url option of the wp command.
  • user - the user to use to run the wp command. Equivalent to the --user option of the wp command.
  • skip-plugins - a boolean value to indicate if the wp command should skip loading plugins. Equivalent to the --skip-plugins option of the wp command.
  • skip-themes - a boolean value to indicate if the wp command should skip loading themes. Equivalent to the --skip-themes option of the wp command.
  • skip-packages - a boolean value to indicate if the wp command should skip loading packages. Equivalent to the --skip-packages option of the wp command.
  • require - a list of PHP files to require before running the wp command. Equivalent to the --require option of the wp command.
  • exec - PHP code to execute before running the wp command. Equivalent to the --exec option of the wp command.
  • context - the context to use when running the wp command. Equivalent to the --context option of the wp command.
  • color - a boolean value to indicate if the wp command should output in color. Equivalent to the --color option of the wp command.
  • no-color - a boolean value to indicate if the wp command should not output in color. Equivalent to the --no-color option of the wp command.
  • debug - a boolean value to indicate if the wp command should output debug information. Equivalent to the --debug option of the wp command.
  • quiet - a boolean value to indicate if the wp command should suppress informational messages. Equivalent to the --quiet option of the wp command.
  • throw - a boolean value to indicate if the wp command should throw an exception if the command fails.
  • timeout - the timeout to use when running the wp command. When the timeout is reached the command will be terminated as a failure.
  • cache-dir - the directory to use to cache the files WPCLI might downloads. Equivalent to setting the WP_CLI_CACHE_DIR environment variable.
  • config-path - the path to the wp-cli.yml file to use. Equivalent to setting the WP_CLI_CONFIG_PATH environment variable.
  • custom-shell - the shell to use to run the wp command. Equivalent to setting the WP_CLI_SHELL environment variable.
  • packages-dir - the directory to use to store the packages downloaded by the wp package command. Equivalent to setting the WP_CLI_PACKAGES_DIR environment variable.

The following is an example of the module configuration to run WPCLI commands on the /var/wordpress directory:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPCLI:\n      path: /var/wordpress\n      throw: true\n

The following configuration uses dynamic configuration parameters to set the module configuration:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPCLI:\n      path: '%WP_ROOT_DIR%'\n      throw: true\n
"},{"location":"modules/WPCLI/#methods","title":"Methods","text":"

The module provides the following methods:

"},{"location":"modules/WPCLI/#changewpclipath","title":"changeWpcliPath","text":"

Signature: changeWpcliPath(string $path) : void

Changes the path to the WordPress installation that WPCLI should use.

This is the equivalent of the --path option.

<?php\n// Operate on the installation specified in the `path` config parameter.\n$I->cli(['core','version']);\n// Change to another installation and run a command there.\n$I->changeWpcliPath('var/wordpress-installation-two');\n$I->cli(['core','version']);\n
"},{"location":"modules/WPCLI/#cli","title":"cli","text":"

Signature: cli([array|string $command], [?array $env], [mixed $input]) : int

Executes a wp-cli command targeting the test WordPress installation.

<?php\n// Activate a plugin via wp-cli in the test WordPress site.\n$I->cli(['plugin', 'activate', 'my-plugin']);\n// Change a user password.\n$I->cli(['user', 'update', 'luca', '--user_pass=newpassword']);\n
"},{"location":"modules/WPCLI/#clitoarray","title":"cliToArray","text":"

Signature: cliToArray(array $command, [?callable $splitCallback], [?array $env], [mixed $input]) : array

Returns the output of a wp-cli command as an array optionally allowing a callback to process the output.

<?php\n// Return a list of inactive themes, like ['twentyfourteen', 'twentyfifteen'].\n$inactiveThemes = $I->cliToArray(['theme', 'list', '--status=inactive', '--field=name']);\n// Get the list of installed plugins and only keep the ones starting with \"foo\".\n$fooPlugins = $I->cliToArray(['plugin', 'list', '--field=name'], function($output){\n     return array_filter(explode(PHP_EOL, $output), function($name){\n             return strpos(trim($name), 'foo') === 0;\n     });\n});\n
"},{"location":"modules/WPCLI/#clitostring","title":"cliToString","text":"

Signature: cliToString(array $command, [?array $env], [mixed $input]) : string

Returns the output of a wp-cli command as a string.

<?php\n// Return the current site administrator email, using string command format.\n$adminEmail = $I->cliToString('option get admin_email');\n// Get the list of active plugins in JSON format, two ways.\n$activePlugins = $I->cliToString(['plugin', 'list','--status=active', '--format=json']);\n$activePlugins = $I->cliToString(['option', 'get', 'active_plugins' ,'--format=json']);\n
"},{"location":"modules/WPCLI/#dontseeinshelloutput","title":"dontSeeInShellOutput","text":"

Signature: dontSeeInShellOutput(string $text) : void

Checks that output from last command doesn't contain text.

<?php\n// Return the current site administrator email, using string command format.\n$I->cli('plugin list --status=active');\n$I->dontSeeInShellOutput('my-inactive/plugin.php');\n
"},{"location":"modules/WPCLI/#dontseeshelloutputmatches","title":"dontSeeShellOutputMatches","text":"

Signature: dontSeeShellOutputMatches(string $regex) : void

Checks that output from the last command doesn't match a given regular expression.

<?php\n// Return the current site administrator email, using string command format.\n$I->cli('option get siteurl');\n$I->dontSeeShellOutputMatches('/^http/');\n
"},{"location":"modules/WPCLI/#grablastcliprocess","title":"grabLastCliProcess","text":"

Signature: grabLastCliProcess() : lucatume\\WPBrowser\\WordPress\\CliProcess

"},{"location":"modules/WPCLI/#grablastshellerroroutput","title":"grabLastShellErrorOutput","text":"

Signature: grabLastShellErrorOutput() : string

Returns the shell error output of the last command.

"},{"location":"modules/WPCLI/#grablastshelloutput","title":"grabLastShellOutput","text":"

Signature: grabLastShellOutput() : string

Returns the shell output of the last command.

"},{"location":"modules/WPCLI/#seeinshelloutput","title":"seeInShellOutput","text":"

Signature: seeInShellOutput(string $text) : void

Checks that output from last command contains text.

<?php\n// Return the current site administrator email, using string command format.\n$I->cli('option get admin_email');\n$I->seeInShellOutput('admin@example.org');\n
"},{"location":"modules/WPCLI/#seeresultcodeis","title":"seeResultCodeIs","text":"

Signature: seeResultCodeIs(int $code) : void

Checks the result code from the last command.

<?php\n// Return the current site administrator email, using string command format.\n$I->cli('option get admin_email');\n$I->seeResultCodeIs(0);\n
"},{"location":"modules/WPCLI/#seeresultcodeisnot","title":"seeResultCodeIsNot","text":"

Signature: seeResultCodeIsNot(int $code) : void

Checks the result code from the last command.

<?php\n// Return the current site administrator email, using string command format.\n$I->cli('invalid command');\n$I->seeResultCodeIsNot(0);\n
"},{"location":"modules/WPCLI/#seeshelloutputmatches","title":"seeShellOutputMatches","text":"

Signature: seeShellOutputMatches(string $regex) : void

Checks that output from the last command matches a given regular expression.

<?php\n// Return the current site administrator email, using string command format.\n$I->cli('option get admin_email');\n$I->seeShellOutputMatches('/^\\S+@\\S+$/');\n

Explore the WP-CLI documentation for more information on the available commands.

"},{"location":"modules/WPDb/","title":"WPDb","text":""},{"location":"modules/WPDb/#wpdb-module","title":"WPDb module","text":"

This module allows to manipulate the database of the WordPress installation under test directly, without using the WordPress API.

The module is used together with the WPBrowser module, WPWebDriver and WPFilesystem modules to control the site state, the database, and the site file structure.

Note about interaction with the WPLoader module: both this module and the WPLoader one can be used to control the state of the database before tests and set up fixtures: use either this or WPLoader, do not use both. This module should be used in end-to-end testing, the WPLoader module should be used in integration testing. If you're using this module to load a database dump before integration tests, use the WPLoader module dump configuration parameter instead.

This module should be with Cest and Cept test cases.

"},{"location":"modules/WPDb/#configuration","title":"Configuration","text":"

This module extends the Codeception Db module adding some configuration options and functions that are specific to WordPress.

  • dbUrl - required; the URL to use to connect to the database. The URL must be in the form mysql://user:password@host:port/database if you're using a MySQL database for your tests, or in the form sqlite://path/to/database/file if you're using a SQLite database for your tests ( like the default configuration does)
  • dsn - required; the DSN to use to connect to the database; required if not using the dbUrl parameter.
  • user - required; the user to use to connect to the database; required if not using the dbUrl parameter.
  • password - required; the password to use to connect to the database; required if not using the dbUrl parameter.
  • url - required;the URL of the WordPress installation under test. E.g. http://localhost:8080 or https://wordpress.test.
  • tablePrefix - the table prefix to use when interacting with the database; defaults to wp_.
  • dump - the path to a database dump file, or a set of database files, to load before running tests. The path can be relative to the project root directory, e.g. tests/_data/dump.sql, or absolute.
  • populate - a boolean value to indicate if the database should be populated importing the dump file(s) at the start of the suite.
  • cleanup - a boolean value to indicate if the database should be populated importing the dump file(s) before each test.
  • reconnect - a boolean value to indicate if the database connection should be re-established before each test.
  • populator - a command to use to populate the database instead of using PHP; read more on the Codeception documentation.
  • urlReplacement - a boolean value to indicate if the database dump file(s) should be searched for the siteurl and home options and replaced with the url parameter value. This is required since WordPress hard-codes URLs in the database, the original URL is inferred, if the originalUrl parameter is not provided.
  • originalUrl - if provided together with the urlReplacement parameter, the module will not try to infer the original URL from the database dump file(s) but use the provided value instead.
  • waitlock - the number of seconds to wait for a database lock to be released before failing the test. Defaults to 10 meaning that the test will fail if the database lock is not released after 10 seconds.
  • createIfNotExists - a boolean value to indicate if the database should be created if it does not exist. Defaults to false.

The following is an example of the module configuration to run tests on thehttp://localhost:8080 site:

modules:\n  enabled:\n    - lucatume\\WPBrowser\\Module\\WPDb:\n        dbUrl: 'mysql://root:password@localhost:3306/wordpress'\n        url: 'http://localhost:8080'\n        tablePrefix: 'wp_'\n        dump: 'tests/_data/dump.sql'\n        populate: true\n        cleanup: true\n        reconnect: false\n        urlReplacement: true\n        originalUrl: http://wordpress.test\n        waitlock: 10\n        createIfNotExists: true\n

The following configuration uses dynamic configuration parameters to set the module configuration:

modules:\n  enabled:\n    - lucatume\\WPBrowser\\Module\\WPDb:\n        dbUrl: '%DB_URL%'\n        url: '%WORDPRESS_URL%'\n        tablePrefix: '%WORDPRESS_TABLE_PREFIX%'\n        dump: '%DB_DUMP%'\n        populate: true\n        cleanup: true\n        reconnect: false\n        urlReplacement: true\n        originalUrl: '%WORDPRESS_ORIGINAL_URL%'\n        waitlock: 10\n        createIfNotExists: true\n

The following configuration uses a SQLite database:

modules:\n  enabled:\n    - lucatume\\WPBrowser\\Module\\WPDb:\n        dbUrl: 'sqlite://tests/database.sqlite'\n        url: 'http://localhost:8080'\n        tablePrefix: 'wp_'\n        dump: 'tests/_data/dump.sql'\n        populate: true\n        cleanup: true\n        reconnect: false\n        urlReplacement: true\n        originalUrl: http://wordpress.test\n        waitlock: 10\n        createIfNotExists: true\n
"},{"location":"modules/WPDb/#methods","title":"Methods","text":""},{"location":"modules/WPDb/#amconnectedtodatabase","title":"amConnectedToDatabase","text":"

Signature: amConnectedToDatabase(string $databaseKey) : void

Make sure you are connected to the right database.

<?php\n$I->seeNumRecords(2, 'users');   //executed on default database\n$I->amConnectedToDatabase('db_books');\n$I->seeNumRecords(30, 'books');  //executed on db_books database\n//All the next queries will be on db_books\n
"},{"location":"modules/WPDb/#countrowsindatabase","title":"countRowsInDatabase","text":"

Signature: countRowsInDatabase(string $table, [array $criteria]) : int

Returns the number of table rows matching a criteria.

<?php\n$I->haveManyPostsInDatabase(3, ['post_status' => 'draft' ]);\n$I->haveManyPostsInDatabase(3, ['post_status' => 'private' ]);\n// Make sure there are now the expected number of draft posts.\n$postsTable = $I->grabPostsTableName();\n$draftsCount = $I->countRowsInDatabase($postsTable, ['post_status' => 'draft']);\n
"},{"location":"modules/WPDb/#donthaveattachmentfilesindatabase","title":"dontHaveAttachmentFilesInDatabase","text":"

Signature: dontHaveAttachmentFilesInDatabase(array|int $attachmentIds) : void

Removes all the files attached with an attachment post, it will not remove the database entries. Requires the WPFilesystem module to be loaded in the suite.

<?php\n$posts = $I->grabPostsTableName();\n$attachmentIds = $I->grabColumnFromDatabase($posts, 'ID', ['post_type' => 'attachment']);\n// This will only remove the files, not the database entries.\n$I->dontHaveAttachmentFilesInDatabase($attachmentIds);\n
"},{"location":"modules/WPDb/#donthaveattachmentindatabase","title":"dontHaveAttachmentInDatabase","text":"

Signature: dontHaveAttachmentInDatabase(array $criteria, [bool $purgeMeta], [bool $removeFiles]) : void

Removes an attachment from the posts table.

$postmeta = $I->grabpostmetatablename();\n$thumbnailId = $I->grabFromDatabase($postmeta, 'meta_value', [\n     'post_id' => $id,\n     'meta_key'=>'thumbnail_id'\n]);\n// Remove only the database entry (including postmeta) but not the files.\n$I->dontHaveAttachmentInDatabase($thumbnailId);\n// Remove the database entry (including postmeta) and the files.\n$I->dontHaveAttachmentInDatabase($thumbnailId, true, true);\n
"},{"location":"modules/WPDb/#donthaveblogindatabase","title":"dontHaveBlogInDatabase","text":"

Signature: dontHaveBlogInDatabase(array $criteria, [bool $removeTables], [bool $removeUploads]) : void

Removes one ore more blogs from the database.

<?php\n// Remove the blog, all its tables and files.\n$I->dontHaveBlogInDatabase(['path' => 'test/one']);\n// Remove the blog entry, not the tables though.\n$I->dontHaveBlogInDatabase(['blog_id' => $blogId]);\n// Remove multiple blogs.\n$I->dontHaveBlogInDatabase(['domain' => 'test']);\n
"},{"location":"modules/WPDb/#donthavecommentindatabase","title":"dontHaveCommentInDatabase","text":"

Signature: dontHaveCommentInDatabase(array $criteria, [bool $purgeMeta]) : void

Removes an entry from the comments table.

<?php\n$I->dontHaveCommentInDatabase(['comment_post_ID' => 23, 'comment_url' => 'http://example.copm']);\n
"},{"location":"modules/WPDb/#donthavecommentmetaindatabase","title":"dontHaveCommentMetaInDatabase","text":"

Signature: dontHaveCommentMetaInDatabase(array $criteria) : void

Removes a post comment meta from the database

<?php\n// Remove all meta for the comment with an ID of 23.\n$I->dontHaveCommentMetaInDatabase(['comment_id' => 23]);\n// Remove the `count` comment meta for the comment with an ID of 23.\n$I->dontHaveCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'count']);\n
"},{"location":"modules/WPDb/#donthaveindatabase","title":"dontHaveInDatabase","text":"

Signature: dontHaveInDatabase(string $table, array $criteria) : void

Deletes a database entry.

<?php\n$I->dontHaveInDatabase('custom_table', ['book_ID' => 23, 'book_genre' => 'fiction']);\n
"},{"location":"modules/WPDb/#donthavelinkindatabase","title":"dontHaveLinkInDatabase","text":"

Signature: dontHaveLinkInDatabase(array $criteria) : void

Removes a link from the database.

<?php\n$I->dontHaveLinkInDatabase(['link_url' => 'http://example.com']);\n
"},{"location":"modules/WPDb/#donthaveoptionindatabase","title":"dontHaveOptionInDatabase","text":"

Signature: dontHaveOptionInDatabase(string $key, [mixed $value]) : void

Removes an entry from the options table.

<?php\n// Remove the `foo` option.\n$I->dontHaveOptionInDatabase('foo');\n// Remove the 'bar' option only if it has the `baz` value.\n$I->dontHaveOptionInDatabase('bar', 'baz');\n
"},{"location":"modules/WPDb/#donthavepostindatabase","title":"dontHavePostInDatabase","text":"

Signature: dontHavePostInDatabase(array $criteria, [bool $purgeMeta]) : void

Removes an entry from the posts table.

<?php\n$posts = $I->haveManyPostsInDatabase(3, ['post_title' => 'Test {{n}}']);\n$I->dontHavePostInDatabase(['post_title' => 'Test 2']);\n
"},{"location":"modules/WPDb/#donthavepostmetaindatabase","title":"dontHavePostMetaInDatabase","text":"

Signature: dontHavePostMetaInDatabase(array $criteria) : void

Removes an entry from the postmeta table.

<?php\n$postId = $I->havePostInDatabase(['meta_input' => ['rating' => 23]]);\n$I->dontHavePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'rating']);\n
"},{"location":"modules/WPDb/#donthavepostthumbnailindatabase","title":"dontHavePostThumbnailInDatabase","text":"

Signature: dontHavePostThumbnailInDatabase(int $postId) : void

Remove the thumbnail (featured image) from a post, if any.

Please note: the method will NOT remove the attachment post, post meta and file.

<?php\n$attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));\n$postId = $I->havePostInDatabase();\n// Attach the thumbnail to the post.\n$I->havePostThumbnailInDatabase($postId, $attachmentId);\n// Remove the thumbnail from the post.\n$I->dontHavePostThumbnailInDatabase($postId);\n
"},{"location":"modules/WPDb/#donthavesiteoptionindatabase","title":"dontHaveSiteOptionInDatabase","text":"

Signature: dontHaveSiteOptionInDatabase(string $key, [mixed $value]) : void

Removes a site option from the database.

<?php\n// Remove the `foo_count` option.\n$I->dontHaveSiteOptionInDatabase('foo_count');\n// Remove the `foo_count` option only if its value is `23`.\n$I->dontHaveSiteOptionInDatabase('foo_count', 23);\n
"},{"location":"modules/WPDb/#donthavesitetransientindatabase","title":"dontHaveSiteTransientInDatabase","text":"

Signature: dontHaveSiteTransientInDatabase(string $key) : void

Removes a site transient from the database.

<?php\n$I->dontHaveSiteTransientInDatabase(['my_plugin_site_buffer']);\n
"},{"location":"modules/WPDb/#donthavetableindatabase","title":"dontHaveTableInDatabase","text":"

Signature: dontHaveTableInDatabase(string $fullTableName) : void

Removes a table from the database. The case where a table does not exist is handled without raising an error.

<?php\n$ordersTable = $I->grabPrefixedTableNameFor('orders');\n$I->dontHaveTableInDatabase($ordersTable);\n
"},{"location":"modules/WPDb/#donthavetermindatabase","title":"dontHaveTermInDatabase","text":"

Signature: dontHaveTermInDatabase(array $criteria, [bool $purgeMeta]) : void

Removes a term from the database.

<?php\n$I->dontHaveTermInDatabase(['name' => 'romance']);\n$I->dontHaveTermInDatabase(['slug' => 'genre--romance']);\n
"},{"location":"modules/WPDb/#donthavetermmetaindatabase","title":"dontHaveTermMetaInDatabase","text":"

Signature: dontHaveTermMetaInDatabase(array $criteria) : void

Removes a term meta from the database.

<?php\n// Remove the \"karma\" key.\n$I->dontHaveTermMetaInDatabase(['term_id' => $termId, 'meta_key' => 'karma']);\n// Remove all meta for the term.\n$I->dontHaveTermMetaInDatabase(['term_id' => $termId]);\n
"},{"location":"modules/WPDb/#donthavetermrelationshipindatabase","title":"dontHaveTermRelationshipInDatabase","text":"

Signature: dontHaveTermRelationshipInDatabase(array $criteria) : void

Removes an entry from the term_relationships table.

<?php\n// Remove the relation between a post and a category.\n$I->dontHaveTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $ttaxId]);\n// Remove all terms for a post.\n$I->dontHaveTermMetaInDatabase(['object_id' => $postId]);\n
"},{"location":"modules/WPDb/#donthavetermtaxonomyindatabase","title":"dontHaveTermTaxonomyInDatabase","text":"

Signature: dontHaveTermTaxonomyInDatabase(array $criteria) : void

Removes an entry from the term_taxonomy table.

<?php\n// Remove a specific term from the genre taxonomy.\n$I->dontHaveTermTaxonomyInDatabase(['term_id' => $postId, 'taxonomy' => 'genre']);\n// Remove all terms for a taxonomy.\n$I->dontHaveTermTaxonomyInDatabase(['taxonomy' => 'genre']);\n
"},{"location":"modules/WPDb/#donthavetransientindatabase","title":"dontHaveTransientInDatabase","text":"

Signature: dontHaveTransientInDatabase(string $transient) : void

Removes a transient from the database.

<?php\n// Removes the `tweets` transient from the database, if set.\n$I->dontHaveTransientInDatabase('tweets');\n
"},{"location":"modules/WPDb/#donthaveuserindatabase","title":"dontHaveUserInDatabase","text":"

Signature: dontHaveUserInDatabase(string|int $userIdOrLogin, [bool $purgeMeta]) : void

Removes a user from the database.

<?php\n$bob = $I->haveUserInDatabase('bob');\n$alice = $I->haveUserInDatabase('alice');\n// Remove Bob's user and meta.\n$I->dontHaveUserInDatabase('bob');\n// Remove Alice's user but not meta.\n$I->dontHaveUserInDatabase($alice);\n
"},{"location":"modules/WPDb/#donthaveuserindatabasewithemail","title":"dontHaveUserInDatabaseWithEmail","text":"

Signature: dontHaveUserInDatabaseWithEmail(string $userEmail, [bool $purgeMeta]) : array

Removes a user(s) from the database using the user email address.

<?php\n$luca = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);\n$I->dontHaveUserInDatabaseWithEmail('luca@exampl.org');\n
"},{"location":"modules/WPDb/#donthaveusermetaindatabase","title":"dontHaveUserMetaInDatabase","text":"

Signature: dontHaveUserMetaInDatabase(array $criteria) : void

Removes an entry from the usermeta table.

<?php\n// Remove the `karma` user meta for a user.\n$I->dontHaveUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);\n// Remove all the user meta for a user.\n$I->dontHaveUserMetaInDatabase(['user_id' => 23]);\n
"},{"location":"modules/WPDb/#dontseeattachmentindatabase","title":"dontSeeAttachmentInDatabase","text":"

Signature: dontSeeAttachmentInDatabase(array $criteria) : void

Checks that an attachment is not in the database.

<?php\n$url = 'https://example.org/images/foo.png';\n$I->dontSeeAttachmentInDatabase(['guid' => $url]);\n
"},{"location":"modules/WPDb/#dontseeblogindatabase","title":"dontSeeBlogInDatabase","text":"

Signature: dontSeeBlogInDatabase(array $criteria) : void

Checks that a row is not present in the blogs table.

<?php\n$I->haveManyBlogsInDatabase(2, ['path' => 'test-{{n}}'], false)\n$I->dontSeeBlogInDatabase(['path' => '/test-3/'])\n
"},{"location":"modules/WPDb/#dontseecommentindatabase","title":"dontSeeCommentInDatabase","text":"

Signature: dontSeeCommentInDatabase(array $criteria) : void

Checks that a comment is not in the database.

Will look up the \"comments\" table.

<?php\n// Checks for one comment.\n$I->dontSeeCommentInDatabase(['comment_ID' => 23]);\n// Checks for comments from a user.\n$I->dontSeeCommentInDatabase(['user_id' => 89]);\n
"},{"location":"modules/WPDb/#dontseecommentmetaindatabase","title":"dontSeeCommentMetaInDatabase","text":"

Signature: dontSeeCommentMetaInDatabase(array $criteria) : void

Checks that a comment meta value is not in the database.

Will look up the \"commentmeta\" table.

<?php\n// Delete a comment `karma` meta.\n$I->dontSeeCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'karma']);\n// Delete all meta for a comment.\n$I->dontSeeCommentMetaInDatabase(['comment_id' => 23]);\n
"},{"location":"modules/WPDb/#dontseeindatabase","title":"dontSeeInDatabase","text":"

Signature: dontSeeInDatabase(string $table, [array $criteria]) : void

"},{"location":"modules/WPDb/#dontseelinkindatabase","title":"dontSeeLinkInDatabase","text":"

Signature: dontSeeLinkInDatabase(array $criteria) : void

Checks that a link is not in the links database table.

<?php\n$I->dontSeeLinkInDatabase(['link_url' => 'http://example.com']);\n$I->dontSeeLinkInDatabase(['link_url' => 'http://example.com', 'link_name' => 'example']);\n
"},{"location":"modules/WPDb/#dontseeoptionindatabase","title":"dontSeeOptionInDatabase","text":"

Signature: dontSeeOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

Checks that an option is not in the database for the current blog.

If the value is an object or an array then the serialized option will be checked.

<?php\n$I->dontHaveOptionInDatabase('posts_per_page');\n$I->dontSeeOptionInDatabase('posts_per_page');\n$I->dontSeeOptionInDatabase('posts_per_page', 23);\n$I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page']);\n$I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page', 'option_value' => 23]);\n
"},{"location":"modules/WPDb/#dontseepageindatabase","title":"dontSeePageInDatabase","text":"

Signature: dontSeePageInDatabase(array $criteria) : void

Checks that a page is not in the database.

<?php\n// Assert a page with an ID does not exist.\n$I->dontSeePageInDatabase(['ID' => 23]);\n// Assert a page with a slug and ID.\n$I->dontSeePageInDatabase(['post_name' => 'test', 'ID' => 23]);\n
"},{"location":"modules/WPDb/#dontseepostindatabase","title":"dontSeePostInDatabase","text":"

Signature: dontSeePostInDatabase(array $criteria) : void

Checks that a post is not in the database.

<?php\n// Asserts a post with title 'Test' is not in the database.\n$I->dontSeePostInDatabase(['post_title' => 'Test']);\n// Asserts a post with title 'Test' and content 'Test content' is not in the database.\n$I->dontSeePostInDatabase(['post_title' => 'Test', 'post_content' => 'Test content']);\n
"},{"location":"modules/WPDb/#dontseepostmetaindatabase","title":"dontSeePostMetaInDatabase","text":"

Signature: dontSeePostMetaInDatabase(array $criteria) : void

Checks that a post meta value does not exist.

If the meta value is an object or an array then the check will be made on its serialized version.

<?php\n$postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']]);\n$I->dontSeePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'woot']);\n
"},{"location":"modules/WPDb/#dontseepostwithtermindatabase","title":"dontSeePostWithTermInDatabase","text":"

Signature: dontSeePostWithTermInDatabase(int $post_id, int $term_taxonomy_id, [?int $term_order], [?string $taxonomy]) : void

Checks that a post to term relation does not exist in the database.

The method will check the \"term_relationships\" table.

<?php\n$fiction = $I->haveTermInDatabase('fiction', 'genre');\n$nonFiction = $I->haveTermInDatabase('non-fiction', 'genre');\n$postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);\n$I->dontSeePostWithTermInDatabase($postId, $nonFiction['term_taxonomy_id], );\n
"},{"location":"modules/WPDb/#dontseesiteoptionindatabase","title":"dontSeeSiteOptionInDatabase","text":"

Signature: dontSeeSiteOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

Checks that a site option is not in the database.

<?php\n// Check that the option is not set in the database.\n$I->dontSeeSiteOptionInDatabase('foo_count');\n// Check that the option is not set with a specific value.\n$I->dontSeeSiteOptionInDatabase('foo_count', 23);\n$I->dontSeeSiteOptionInDatabase(['option_name => 'foo_count', 'option_value' => 23]);\n
"},{"location":"modules/WPDb/#dontseesitetransientindatabase","title":"dontSeeSiteTransientInDatabase","text":"

Signature: dontSeeSiteTransientInDatabase(string $transient, [mixed $value]) : void

Checks that a site transient is not in the database.

<?php\n$I->dontSeeSiteTransientInDatabase('foo');\n$I->dontSeeSiteTransientInDatabase('foo', 23);\n
"},{"location":"modules/WPDb/#dontseetableindatabase","title":"dontSeeTableInDatabase","text":"

Signature: dontSeeTableInDatabase(string $table) : void

Checks that a table is not in the database.

<?php\n$options = $I->grabPrefixedTableNameFor('options');\n$I->dontHaveTableInDatabase($options)\n$I->dontSeeTableInDatabase($options);\n
"},{"location":"modules/WPDb/#dontseetermindatabase","title":"dontSeeTermInDatabase","text":"

Signature: dontSeeTermInDatabase(array $criteria) : void

Makes sure a term is not in the database.

Looks up both the terms table and the term_taxonomy tables.

<?php\n// Asserts a 'fiction' term is not in the database.\n$I->dontSeeTermInDatabase(['name' => 'fiction']);\n// Asserts a 'fiction' term with slug 'genre--fiction' is not in the database.\n$I->dontSeeTermInDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);\n
"},{"location":"modules/WPDb/#dontseetermmetaindatabase","title":"dontSeeTermMetaInDatabase","text":"

Signature: dontSeeTermMetaInDatabase(array $criteria) : void

Checks that a term meta is not in the database.

<?php\nlist($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n$I->haveTermMetaInDatabase($termId, 'rating', 4);\n$I->dontSeeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'average_review']);\n
"},{"location":"modules/WPDb/#dontseetermtaxonomyindatabase","title":"dontSeeTermTaxonomyInDatabase","text":"

Signature: dontSeeTermTaxonomyInDatabase(array $criteria) : void

Checks that a term taxonomy is not in the database.

<?php\nlist($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n$I->dontSeeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'country']);\n
"},{"location":"modules/WPDb/#dontseetransientindatabase","title":"dontSeeTransientInDatabase","text":"

Signature: dontSeeTransientInDatabase(string $transient, [mixed $value]) : void

Checks that a transient is not in the database.

<?php\n$I->dontSeeTransientInDatabase('foo');\n$I->dontSeeTransientInDatabase('foo', 23);\n
"},{"location":"modules/WPDb/#dontseeuserindatabase","title":"dontSeeUserInDatabase","text":"

Signature: dontSeeUserInDatabase(array $criteria) : void

Checks that a user is not in the database.

<?php\n// Asserts a user does not exist in the database.\n$I->dontSeeUserInDatabase(['user_login' => 'luca']);\n// Asserts a user with email and login is not in the database.\n$I->dontSeeUserInDatabase(['user_login' => 'luca', 'user_email' => 'luca@theaveragedev.com']);\n
"},{"location":"modules/WPDb/#dontseeusermetaindatabase","title":"dontSeeUserMetaInDatabase","text":"

Signature: dontSeeUserMetaInDatabase(array $criteria) : void

Check that a user meta value is not in the database.

<?php\n// Asserts a user does not have a 'karma' meta assigned.\n$I->dontSeeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);\n// Asserts no user has any 'karma' meta assigned.\n$I->dontSeeUserMetaInDatabase(['meta_key' => 'karma']);\n
"},{"location":"modules/WPDb/#getsitedomain","title":"getSiteDomain","text":"

Signature: getSiteDomain() : string

Returns the site domain inferred from the url set in the config.

<?php\n$domain = $I->getSiteDomain();\n// We should be redirected to the HTTPS version when visiting the HTTP version.\n$I->amOnPage('http://' . $domain);\n$I->seeCurrentUrlEquals('https://' . $domain);\n
"},{"location":"modules/WPDb/#getuserstablename","title":"getUsersTableName","text":"

Signature: getUsersTableName() : string

Returns the prefixed users table name.

<?php\n// Given a `wp_` table prefix returns `wp_users`.\n$usersTable = $I->getUsersTableName();\n// Given a `wp_` table prefix returns `wp_users`.\n$I->useBlog(23);\n$usersTable = $I->getUsersTableName();\n
"},{"location":"modules/WPDb/#graballfromdatabase","title":"grabAllFromDatabase","text":"

Signature: grabAllFromDatabase(string $table, string $column, array $criteria) : array

Returns all entries matching a criteria from the database.

<?php\n$books = $I->grabPrefixedTableNameFor('books');\n$I->grabAllFromDatabase($books, 'title', ['genre' => 'fiction']);\n
"},{"location":"modules/WPDb/#grabattachmentattachedfile","title":"grabAttachmentAttachedFile","text":"

Signature: grabAttachmentAttachedFile(int $attachmentPostId) : string

Returns the path, as stored in the database, of an attachment _wp_attached_file meta. The attached file is, usually, an attachment origal file.

<?php\n$file = $I->grabAttachmentAttachedFile($attachmentId);\n$fileInfo = new SplFileInfo($file);\n$I->assertEquals('jpg', $fileInfo->getExtension());\n
"},{"location":"modules/WPDb/#grabattachmentmetadata","title":"grabAttachmentMetadata","text":"

Signature: grabAttachmentMetadata(int $attachmentPostId) : array

Returns the metadata array for an attachment post. This is the value of the _wp_attachment_metadata meta.

<?php\n$metadata = $I->grabAttachmentMetadata($attachmentId);\n$I->assertEquals(['thumbnail', 'medium', 'medium_large'], array_keys($metadata['sizes']);\n
"},{"location":"modules/WPDb/#grabblogdomain","title":"grabBlogDomain","text":"

Signature: grabBlogDomain(int $blogId) : string

Returns a blog domain given its ID.

<?php\n$blogIds = $I->haveManyBlogsInDatabase(3);\n$domains = array_map(function($blogId){\n     return $I->grabBlogDomain($blogId);\n}, $blogIds);\n
"},{"location":"modules/WPDb/#grabblogpath","title":"grabBlogPath","text":"

Signature: grabBlogPath(int $blogId) : string

Grabs a blog domain from the blogs table.

<?php\n$blogId = $I->haveBlogInDatabase('test');\n$path = $I->grabBlogDomain($blogId);\n$I->amOnSubdomain($path);\n$I->amOnPage('/');\n
"},{"location":"modules/WPDb/#grabblogtablename","title":"grabBlogTableName","text":"

Signature: grabBlogTableName(int $blogId, string $table) : string

Returns the full name of a table for a blog from a multisite installation database.

<?php\n$blogOptionTable = $I->grabBlogTableName($blogId, 'option');\n
"},{"location":"modules/WPDb/#grabblogtablenames","title":"grabBlogTableNames","text":"

Signature: grabBlogTableNames(int $blogId) : array

Returns a list of tables for a blog ID.

<?php\n     $blogId = $I->haveBlogInDatabase('test');\n     $tables = $I->grabBlogTableNames($blogId);\n     $options = array_filter($tables, function($tableName){\n     return str_pos($tableName, 'options') !== false;\n});\n
"},{"location":"modules/WPDb/#grabblogtableprefix","title":"grabBlogTablePrefix","text":"

Signature: grabBlogTablePrefix(int $blogId) : string

Returns the table prefix for a blog.

<?php\n$blogId = $I->haveBlogInDatabase('test');\n$blogTablePrefix = $I->getBlogTablePrefix($blogId);\n$blogOrders = $I->blogTablePrefix . 'orders';\n
"},{"location":"modules/WPDb/#grabblogurl","title":"grabBlogUrl","text":"

Signature: grabBlogUrl([int $blogId]) : string

Gets the blog URL from the Blog ID.

"},{"location":"modules/WPDb/#grabblogversionstablename","title":"grabBlogVersionsTableName","text":"

Signature: grabBlogVersionsTableName() : string

Gets the prefixed blog_versions table name.

<?php\n// Assuming a `wp_` table prefix it will return `wp_blog_versions`.\n$blogVersionsTable = $I->grabBlogVersionsTableName();\n$I->useBlog(23);\n// Assuming a `wp_` table prefix it will return `wp_blog_versions`.\n$blogVersionsTable = $I->grabBlogVersionsTableName();\n
"},{"location":"modules/WPDb/#grabblogstablename","title":"grabBlogsTableName","text":"

Signature: grabBlogsTableName() : string

Gets the prefixed blogs table name.

<?php\n// Assuming a `wp_` table prefix it will return `wp_blogs`.\n$blogVersionsTable = $I->grabBlogsTableName();\n$I->useBlog(23);\n// Assuming a `wp_` table prefix it will return `wp_blogs`.\n$blogVersionsTable = $I->grabBlogsTableName();\n
"},{"location":"modules/WPDb/#grabcolumnfromdatabase","title":"grabColumnFromDatabase","text":"

Signature: grabColumnFromDatabase(string $table, string $column, [array $criteria]) : array

Fetches all values from the column in database. Provide table name, desired column and criteria.

<?php\n$mails = $I->grabColumnFromDatabase('users', 'email', array('name' => 'RebOOter'));\n
"},{"location":"modules/WPDb/#grabcommentmetatablename","title":"grabCommentmetaTableName","text":"

Signature: grabCommentmetaTableName() : string

Returns the prefixed comment meta table name.

<?php\n// Get all the values of 'karma' for all comments.\n$commentMeta = $I->grabCommentmetaTableName();\n$I->grabAllFromDatabase($commentMeta, 'meta_value', ['meta_key' => 'karma']);\n
"},{"location":"modules/WPDb/#grabcommentstablename","title":"grabCommentsTableName","text":"

Signature: grabCommentsTableName() : string

Gets the comments table name.

<?php\n// Will be `wp_comments`.\n$comments = $I->grabCommentsTableName();\n// Will be `wp_23_comments`.\n$I->useBlog(23);\n$comments = $I->grabCommentsTableName();\n
"},{"location":"modules/WPDb/#grabentriesfromdatabase","title":"grabEntriesFromDatabase","text":"

Signature: grabEntriesFromDatabase(string $table, [array $criteria]) : array

Fetches a set of entries from a database. Provide table name and criteria.

<?php\n$mail = $I->grabEntriesFromDatabase('users', array('name' => 'Davert'));\n
Comparison expressions can be used as well:

<?php\n$post = $I->grabEntriesFromDatabase('posts', ['num_comments >=' => 100]);\n$user = $I->grabEntriesFromDatabase('users', ['email like' => 'miles%']);\n

Supported operators: <, >, >=, <=, !=, like.

"},{"location":"modules/WPDb/#grabentryfromdatabase","title":"grabEntryFromDatabase","text":"

Signature: grabEntryFromDatabase(string $table, [array $criteria]) : array

Fetches a whole entry from a database. Make the test fail if the entry is not found. Provide table name, desired column and criteria.

<?php\n$mail = $I->grabEntryFromDatabase('users', array('name' => 'Davert'));\n
Comparison expressions can be used as well:

<?php\n$post = $I->grabEntryFromDatabase('posts', ['num_comments >=' => 100]);\n$user = $I->grabEntryFromDatabase('users', ['email like' => 'miles%']);\n

Supported operators: <, >, >=, <=, !=, like.

"},{"location":"modules/WPDb/#grabfromdatabase","title":"grabFromDatabase","text":"

Signature: grabFromDatabase(string $table, string $column, [array $criteria]) : void

Fetches a single column value from a database. Provide table name, desired column and criteria.

<?php\n$mail = $I->grabFromDatabase('users', 'email', array('name' => 'Davert'));\n
Comparison expressions can be used as well:

<?php\n$postNum = $I->grabFromDatabase('posts', 'num_comments', ['num_comments >=' => 100]);\n$mail = $I->grabFromDatabase('users', 'email', ['email like' => 'miles%']);\n

Supported operators: <, >, >=, <=, !=, like.

"},{"location":"modules/WPDb/#grablatestentrybyfromdatabase","title":"grabLatestEntryByFromDatabase","text":"

Signature: grabLatestEntryByFromDatabase(string $tableName, [string $idColumn]) : int

Returns the id value of the last table entry.

<?php\n$I->haveManyPostsInDatabase();\n$postsTable = $I->grabPostsTableName();\n$last = $I->grabLatestEntryByFromDatabase($postsTable, 'ID');\n
"},{"location":"modules/WPDb/#grablinkstablename","title":"grabLinksTableName","text":"

Signature: grabLinksTableName() : string

Returns the prefixed links table name.

<?php\n// Given a `wp_` table prefix returns `wp_links`.\n$linksTable = $I->grabLinksTableName();\n// Given a `wp_` table prefix returns `wp_23_links`.\n$I->useBlog(23);\n$linksTable = $I->grabLinksTableName();\n
"},{"location":"modules/WPDb/#grabnumrecords","title":"grabNumRecords","text":"

Signature: grabNumRecords(string $table, [array $criteria]) : int

Returns the number of rows in a database

"},{"location":"modules/WPDb/#graboptionfromdatabase","title":"grabOptionFromDatabase","text":"

Signature: grabOptionFromDatabase(string $option_name) : mixed

Gets an option value from the database.

<?php\n$count = $I->grabOptionFromDatabase('foo_count');\n
"},{"location":"modules/WPDb/#grabpostfieldfromdatabase","title":"grabPostFieldFromDatabase","text":"

Signature: grabPostFieldFromDatabase(int $postId, string $field) : mixed

Returns the value of a post field for a post, from the posts table.

<?php\n$title = $I->grabPostFieldFromDatabase(1, 'post_title');\n$type = $I->grabPostFieldFromDatabase(1, 'post_type');\n
"},{"location":"modules/WPDb/#grabpostmetafromdatabase","title":"grabPostMetaFromDatabase","text":"

Signature: grabPostMetaFromDatabase(int $postId, string $metaKey, [bool $single]) : mixed

Gets the value of one or more post meta values from the database.

<?php\n$thumbnail_id = $I->grabPostMetaFromDatabase($postId, '_thumbnail_id', true);\n
"},{"location":"modules/WPDb/#grabpostmetatablename","title":"grabPostmetaTableName","text":"

Signature: grabPostmetaTableName() : string

Returns the prefixed post meta table name.

<?php\n// Returns 'wp_postmeta'.\n$I->grabPostmetaTableName();\n// Returns 'wp_23_postmeta'.\n$I->useBlog(23);\n$I->grabPostmetaTableName();\n
"},{"location":"modules/WPDb/#grabpoststablename","title":"grabPostsTableName","text":"

Signature: grabPostsTableName() : string

Gets the posts prefixed table name.

<?php\n// Given a `wp_` table prefix returns `wp_posts`.\n$postsTable = $I->grabPostsTableName();\n// Given a `wp_` table prefix returns `wp_23_posts`.\n$I->useBlog(23);\n$postsTable = $I->grabPostsTableName();\n
"},{"location":"modules/WPDb/#grabprefixedtablenamefor","title":"grabPrefixedTableNameFor","text":"

Signature: grabPrefixedTableNameFor([string $tableName]) : string

Returns a prefixed table name for the current blog.

If the table is not one to be prefixed (e.g. users) then the proper table name will be returned.

<?php\n// Will return wp_users.\n$usersTable = $I->grabPrefixedTableNameFor('users');\n// Will return wp_options.\n$optionsTable = $I->grabPrefixedTableNameFor('options');\n// Use a different blog and get its options table.\n$I->useBlog(2);\n$blogOptionsTable = $I->grabPrefixedTableNameFor('options');\n
"},{"location":"modules/WPDb/#grabregistrationlogtablename","title":"grabRegistrationLogTableName","text":"

Signature: grabRegistrationLogTableName() : string

Gets the prefixed registration_log table name.

<?php\n// Assuming a `wp_` table prefix it will return `wp_registration_log`.\n$blogVersionsTable = $I->grabRegistrationLogTableName();\n$I->useBlog(23);\n// Assuming a `wp_` table prefix it will return `wp_registration_log`.\n$blogVersionsTable = $I->grabRegistrationLogTableName();\n
"},{"location":"modules/WPDb/#grabsignupstablename","title":"grabSignupsTableName","text":"

Signature: grabSignupsTableName() : string

Gets the prefixed signups table name.

<?php\n// Assuming a `wp_` table prefix it will return `wp_signups`.\n$blogVersionsTable = $I->grabSignupsTableName();\n$I->useBlog(23);\n// Assuming a `wp_` table prefix it will return `wp_signups`.\n$blogVersionsTable = $I->grabSignupsTableName();\n
"},{"location":"modules/WPDb/#grabsitemetafromdatabase","title":"grabSiteMetaFromDatabase","text":"

Signature: grabSiteMetaFromDatabase(int $blogId, string $key, bool $single) : mixed

Returns a single or all meta values for a site meta key.

<?php\n$I->haveSiteMetaInDatabase(1, 'foo', 'bar');\n$value = $I->grabSiteMetaFromDatabase(1, 'foo', true);\n$values = $I->grabSiteMetaFromDatabase(1, 'foo', false);\n
"},{"location":"modules/WPDb/#grabsitemetatablename","title":"grabSiteMetaTableName","text":"

Signature: grabSiteMetaTableName() : string

Gets the prefixed sitemeta table name.

<?php\n// Assuming a `wp_` table prefix it will return `wp_sitemeta`.\n$blogVersionsTable = $I->grabSiteMetaTableName();\n$I->useBlog(23);\n// Assuming a `wp_` table prefix it will return `wp_sitemeta`.\n$blogVersionsTable = $I->grabSiteMetaTableName();\n
"},{"location":"modules/WPDb/#grabsiteoptionfromdatabase","title":"grabSiteOptionFromDatabase","text":"

Signature: grabSiteOptionFromDatabase(string $key) : mixed

Gets a site option from the database.

<?php\n$fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');\n
"},{"location":"modules/WPDb/#grabsitetablename","title":"grabSiteTableName","text":"

Signature: grabSiteTableName() : string

Gets the prefixed site table name.

<?php\n// Assuming a `wp_` table prefix it will return `wp_site`.\n$blogVersionsTable = $I->grabSiteTableName();\n$I->useBlog(23);\n// Assuming a `wp_` table prefix it will return `wp_site`.\n$blogVersionsTable = $I->grabSiteTableName();\n
"},{"location":"modules/WPDb/#grabsitetransientfromdatabase","title":"grabSiteTransientFromDatabase","text":"

Signature: grabSiteTransientFromDatabase(string $key) : mixed

Gets a site transient from the database.

<?php\n$I->grabSiteTransientFromDatabase('total_comments');\n$I->grabSiteTransientFromDatabase('api_data');\n
"},{"location":"modules/WPDb/#grabsiteurl","title":"grabSiteUrl","text":"

Signature: grabSiteUrl([?string $path]) : string

Returns the current site URL as specified in the module configuration.

<?php\n$shopPath = $I->grabSiteUrl('/shop');\n
"},{"location":"modules/WPDb/#grabtableprefix","title":"grabTablePrefix","text":"

Signature: grabTablePrefix() : string

Returns the table prefix, namespaced for secondary blogs if selected.

<?php\n// Assuming a table prefix of `wp_` it will return `wp_`;\n$tablePrefix = $I->grabTablePrefix();\n$I->useBlog(23);\n// Assuming a table prefix of `wp_` it will return `wp_23_`;\n$tablePrefix = $I->grabTablePrefix();\n
"},{"location":"modules/WPDb/#grabtermidfromdatabase","title":"grabTermIdFromDatabase","text":"

Signature: grabTermIdFromDatabase(array $criteria) : int|false

Gets a term ID from the database. Looks up the prefixed terms table, e.g. wp_terms.

<?php\n// Return the 'fiction' term 'term_id'.\n$termId = $I->grabTermIdFromDatabase(['name' => 'fiction']);\n// Get a term ID by more stringent criteria.\n$termId = $I->grabTermIdFromDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);\n// Return the 'term_id' of the first term for a group.\n$termId = $I->grabTermIdFromDatabase(['term_group' => 23]);\n
"},{"location":"modules/WPDb/#grabtermmetatablename","title":"grabTermMetaTableName","text":"

Signature: grabTermMetaTableName() : string

Gets the terms meta table prefixed name.

<?php\n// Returns 'wp_termmeta'.\n$I->grabTermMetaTableName();\n// Returns 'wp_23_termmeta'.\n$I->useBlog(23);\n$I->grabTermMetaTableName();\n
"},{"location":"modules/WPDb/#grabtermrelationshipstablename","title":"grabTermRelationshipsTableName","text":"

Signature: grabTermRelationshipsTableName() : string

Gets the prefixed term relationships table name, e.g. wp_term_relationships.

<?php\n$I->grabTermRelationshipsTableName();\n
"},{"location":"modules/WPDb/#grabtermtaxonomyidfromdatabase","title":"grabTermTaxonomyIdFromDatabase","text":"

Signature: grabTermTaxonomyIdFromDatabase(array $criteria) : int|false

Gets a term_taxonomy_id from the database.

Looks up the prefixed terms_relationships table, e.g. wp_term_relationships.

<?php\n// Get the `term_taxonomy_id` for a term and a taxonomy.\n$I->grabTermTaxonomyIdFromDatabase(['term_id' => $fictionId, 'taxonomy' => 'genre']);\n// Get the `term_taxonomy_id` for the first term with a count of 23.\n$I->grabTermTaxonomyIdFromDatabase(['count' => 23]);\n
"},{"location":"modules/WPDb/#grabtermtaxonomytablename","title":"grabTermTaxonomyTableName","text":"

Signature: grabTermTaxonomyTableName() : string

Gets the prefixed term and taxonomy table name, e.g. wp_term_taxonomy.

<?php\n// Returns 'wp_term_taxonomy'.\n$I->grabTermTaxonomyTableName();\n// Returns 'wp_23_term_taxonomy'.\n$I->useBlog(23);\n$I->grabTermTaxonomyTableName();\n
"},{"location":"modules/WPDb/#grabtermstablename","title":"grabTermsTableName","text":"

Signature: grabTermsTableName() : string

Gets the prefixed terms table name, e.g. wp_terms.

<?php\n// Returns 'wp_terms'.\n$I->grabTermsTableName();\n// Returns 'wp_23_terms'.\n$I->useBlog(23);\n$I->grabTermsTableName();\n
"},{"location":"modules/WPDb/#grabtransientfromdatabase","title":"grabTransientFromDatabase","text":"

Signature: grabTransientFromDatabase(string $transient) : mixed

Fetches the value of a transient from the database.

<?php\n$I->haveTransientInDatabase('foo', 23);\n$transientValue = $I->grabTransientFromDatabase('foo');\n$I->assertEquals(23, $transientValue);\n
"},{"location":"modules/WPDb/#grabuseridfromdatabase","title":"grabUserIdFromDatabase","text":"

Signature: grabUserIdFromDatabase(string $userLogin) : int|false

Gets the a user ID from the database using the user login.

<?php\n$userId = $I->grabUserIdFromDatabase('luca');\n
"},{"location":"modules/WPDb/#grabusermetafromdatabase","title":"grabUserMetaFromDatabase","text":"

Signature: grabUserMetaFromDatabase(int $userId, string $meta_key, [bool $single]) : mixed

Gets a user meta from the database.

<?php\n// Returns a user 'karma' value.\n$I->grabUserMetaFromDatabase($userId, 'karma');\n// Returns an array, the unserialized version of the value stored in the database.\n$I->grabUserMetaFromDatabase($userId, 'api_data');\n
"},{"location":"modules/WPDb/#grabusermetatablename","title":"grabUsermetaTableName","text":"

Signature: grabUsermetaTableName() : string

Returns the prefixed users meta table name.

<?php\n// Given a `wp_` table prefix returns `wp_usermeta`.\n$usermetaTable = $I->grabUsermetaTableName();\n// Given a `wp_` table prefix returns `wp_usermeta`.\n$I->useBlog(23);\n$usermetaTable = $I->grabUsermetaTableName();\n
"},{"location":"modules/WPDb/#grabuserstablename","title":"grabUsersTableName","text":"

Signature: grabUsersTableName() : string

Returns the prefixed users table name.

<?php\n// Given a `wp_` table prefix returns `wp_users`.\n$usersTable = $I->grabUsersTableName();\n// Given a `wp_` table prefix returns `wp_users`.\n$I->useBlog(23);\n$usersTable = $I->grabUsersTableName();\n
"},{"location":"modules/WPDb/#haveattachmentindatabase","title":"haveAttachmentInDatabase","text":"

Signature: haveAttachmentInDatabase(string $file, [string|int $date], [array $overrides], [?array $imageSizes]) : int

Creates the database entries representing an attachment and moves the attachment file to the right location.

<?php\n$file = codecept_data_dir('images/test.png');\n$attachmentId = $I->haveAttachmentInDatabase($file);\n$image = codecept_data_dir('images/test-2.png');\n$lastWeekAttachment = $I->haveAttachmentInDatabase($image, '-1 week');\n

Requires the WPFilesystem module.

"},{"location":"modules/WPDb/#haveblogindatabase","title":"haveBlogInDatabase","text":"

Signature: haveBlogInDatabase(string $domainOrPath, [array $overrides], [bool $subdomain]) : int

Inserts a blog in the blogs table.

<?php\n// Create the `test` subdomain blog.\n$blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId]);\n// Create the `/test` subfolder blog.\n$blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId], false);\n
"},{"location":"modules/WPDb/#havecommentindatabase","title":"haveCommentInDatabase","text":"

Signature: haveCommentInDatabase(int $comment_post_ID, [array $data]) : int

Inserts a comment in the database.

<?php\n$I->haveCommentInDatabase($postId, ['comment_content' => 'Test Comment', 'comment_karma' => 23]);\n
"},{"location":"modules/WPDb/#havecommentmetaindatabase","title":"haveCommentMetaInDatabase","text":"

Signature: haveCommentMetaInDatabase(int $comment_id, string $meta_key, mixed $meta_value) : int

Inserts a comment meta field in the database. Array and object meta values will be serialized.

<?php\n$I->haveCommentMetaInDatabase($commentId, 'api_ID', 23);\n// The value will be serialized.\n$apiData = ['ID' => 23, 'user' => 89, 'origin' => 'twitter'];\n$I->haveCommentMetaInDatabase($commentId, 'api_data', $apiData);\n
"},{"location":"modules/WPDb/#haveindatabase","title":"haveInDatabase","text":"

Signature: haveInDatabase(string $table, array $data) : int

Inserts an SQL record into a database. This record will be erased after the test, unless you've configured \"skip_cleanup_if_failed\", and the test fails.

<?php\n$I->haveInDatabase('users', array('name' => 'miles', 'email' => 'miles@davis.com'));\n
"},{"location":"modules/WPDb/#havelinkindatabase","title":"haveLinkInDatabase","text":"

Signature: haveLinkInDatabase([array $overrides]) : int

Inserts a link in the database.

<?php\n$linkId = $I->haveLinkInDatabase(['link_url' => 'http://example.org']);\n
"},{"location":"modules/WPDb/#havemanyblogsindatabase","title":"haveManyBlogsInDatabase","text":"

Signature: haveManyBlogsInDatabase(int $count, [array $overrides], [bool $subdomain]) : array

Inserts many blogs in the database.

<?php\n     $blogIds = $I->haveManyBlogsInDatabase(3, ['domain' =>'test-{{n}}']);\n     foreach($blogIds as $blogId){\n     $I->useBlog($blogId);\n     $I->haveManuPostsInDatabase(3);\n}\n
"},{"location":"modules/WPDb/#havemanycommentsindatabase","title":"haveManyCommentsInDatabase","text":"

Signature: haveManyCommentsInDatabase(int $count, int $comment_post_ID, [array $overrides]) : array

Inserts many comments in the database.

<?php\n// Insert 3 random comments for a post.\n$I->haveManyCommentsInDatabase(3, $postId);\n// Insert 3 random comments for a post.\n$I->haveManyCommentsInDatabase(3, $postId, ['comment_content' => 'Comment {{n}}']);\n
"},{"location":"modules/WPDb/#havemanylinksindatabase","title":"haveManyLinksInDatabase","text":"

Signature: haveManyLinksInDatabase(int $count, [array $overrides]) : array

Inserts many links in the database links table.

<?php\n// Insert 3 randomly generated links in the database.\n$linkIds = $I->haveManyLinksInDatabase(3);\n// Inserts links in the database replacing the `n` placeholder.\n$linkIds = $I->haveManyLinksInDatabase(3, ['link_url' => 'http://example.org/test-{{n}}']);\n
"},{"location":"modules/WPDb/#havemanypostsindatabase","title":"haveManyPostsInDatabase","text":"

Signature: haveManyPostsInDatabase(int $count, [array $overrides]) : array

Inserts many posts in the database returning their IDs.

<?php\n// Insert 3 random posts.\n$I->haveManyPostsInDatabase(3);\n// Insert 3 posts with generated titles.\n$I->haveManyPostsInDatabase(3, ['post_title' => 'Test post {{n}}']);\n
"},{"location":"modules/WPDb/#havemanytermsindatabase","title":"haveManyTermsInDatabase","text":"

Signature: haveManyTermsInDatabase(int $count, string $name, string $taxonomy, [array $overrides]) : array

Inserts many terms in the database.

<?php\n$terms = $I->haveManyTermsInDatabase(3, 'genre-{{n}}', 'genre');\n$termIds = array_column($terms, 0);\n$termTaxonomyIds = array_column($terms, 1);\n
"},{"location":"modules/WPDb/#havemanyusersindatabase","title":"haveManyUsersInDatabase","text":"

Signature: haveManyUsersInDatabase(int $count, string $user_login, [string $role], [array $overrides]) : array

Inserts many users in the database.

<?php\n$subscribers = $I->haveManyUsersInDatabase(5, 'user-{{n}}');\n$editors = $I->haveManyUsersInDatabase(\n     5,\n     'user-{{n}}',\n     'editor',\n     ['user_email' => 'user-{{n}}@example.org']\n);\n
"},{"location":"modules/WPDb/#havemenuindatabase","title":"haveMenuInDatabase","text":"

Signature: haveMenuInDatabase(string $slug, string $location, [array $overrides]) : array

Creates and adds a menu to a theme location in the database.

<?php\nlist($termId, $termTaxId) = $I->haveMenuInDatabase('test', 'sidebar');\n
"},{"location":"modules/WPDb/#havemenuitemindatabase","title":"haveMenuItemInDatabase","text":"

Signature: haveMenuItemInDatabase(string $menuSlug, string $title, [?int $menuOrder], [array $meta]) : int

Adds a menu element to a menu for the current theme.

<?php\n$I->haveMenuInDatabase('test', 'sidebar');\n$I->haveMenuItemInDatabase('test', 'Test one', 0);\n$I->haveMenuItemInDatabase('test', 'Test two', 1);\n
"},{"location":"modules/WPDb/#haveoptionindatabase","title":"haveOptionInDatabase","text":"

Signature: haveOptionInDatabase(string $option_name, mixed $option_value, [string $autoload]) : int

Inserts an option in the database.

<?php\n$I->haveOptionInDatabase('posts_per_page', 23);\n$I->haveOptionInDatabase('my_plugin_options', ['key_one' => 'value_one', 'key_two' => 89]);\n

If the option value is an object or an array then the value will be serialized.

"},{"location":"modules/WPDb/#havepageindatabase","title":"havePageInDatabase","text":"

Signature: havePageInDatabase([array $overrides]) : int

Inserts a page in the database.

<?php\n// Creates a test page in the database with random values.\n$randomPageId = $I->havePageInDatabase();\n// Creates a test page in the database defining its title.\n$testPageId = $I->havePageInDatabase(['post_title' => 'Test page']);\n
"},{"location":"modules/WPDb/#havepostindatabase","title":"havePostInDatabase","text":"

Signature: havePostInDatabase([array $data]) : int

Inserts a post in the database.

<?php\n// Insert a post with random values in the database.\n$randomPostId = $I->havePostInDatabase();\n// Insert a post with specific values in the database.\n$I->havePostInDatabase([\n'post_type' => 'book',\n'post_title' => 'Alice in Wonderland',\n'meta_input' => [\n'readers_count' => 23\n],\n'tax_input' => [\n['genre' => 'fiction']\n]\n]);\n
"},{"location":"modules/WPDb/#havepostthumbnailindatabase","title":"havePostThumbnailInDatabase","text":"

Signature: havePostThumbnailInDatabase(int $postId, int $thumbnailId) : int

Assigns the specified attachment ID as thumbnail (featured image) to a post.

<?php\n$attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));\n$postId = $I->havePostInDatabase();\n$I->havePostThumbnailInDatabase($postId, $attachmentId);\n
"},{"location":"modules/WPDb/#havepostmetaindatabase","title":"havePostmetaInDatabase","text":"

Signature: havePostmetaInDatabase(int $postId, string $meta_key, mixed $meta_value) : int

Adds one or more meta key and value couples in the database for a post.

<?php\n// Set the post-meta for a post.\n$I->havePostmetaInDatabase($postId, 'karma', 23);\n// Set an array post-meta for a post, it will be serialized in the db.\n$I->havePostmetaInDatabase($postId, 'data', ['one', 'two']);\n// Use a loop to insert one meta per row.\nforeach( ['one', 'two'] as $value){\n     $I->havePostmetaInDatabase($postId, 'data', $value);\n}\n
"},{"location":"modules/WPDb/#havesitemetaindatabase","title":"haveSiteMetaInDatabase","text":"

Signature: haveSiteMetaInDatabase(int $blogId, string $string, mixed $value) : int

Adds a meta key and value for a site in the database.

<?php\n$I->haveSiteMetaInDatabase(1, 'foo', 'bar');\n$insertedId = $I->haveSiteMetaInDatabase(2, 'foo', ['bar' => 'baz']);\n
"},{"location":"modules/WPDb/#havesiteoptionindatabase","title":"haveSiteOptionInDatabase","text":"

Signature: haveSiteOptionInDatabase(string $key, mixed $value) : int

Inserts a site option in the database.

If the value is an array or an object then the value will be serialized.

<?php\n$fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');\n
"},{"location":"modules/WPDb/#havesitetransientindatabase","title":"haveSiteTransientInDatabase","text":"

Signature: haveSiteTransientInDatabase(string $key, mixed $value) : int

Inserts a site transient in the database. If the value is an array or an object then the value will be serialized.

<?php\n$I->haveSiteTransientInDatabase('total_comments_count', 23);\n// This value will be serialized.\n$I->haveSiteTransientInDatabase('api_data', ['user' => 'luca', 'token' => '11ae3ijns-j83']);\n
"},{"location":"modules/WPDb/#havetermindatabase","title":"haveTermInDatabase","text":"

Signature: haveTermInDatabase(string $name, string $taxonomy, [array $overrides]) : array

Inserts a term in the database.

<?php\n// Insert a random 'genre' term in the database.\n$I->haveTermInDatabase('non-fiction', 'genre');\n// Insert a term in the database with term meta.\n$I->haveTermInDatabase('fiction', 'genre', [\n     'slug' => 'genre--fiction',\n     'meta' => [\n        'readers_count' => 23\n     ]\n]);\n
"},{"location":"modules/WPDb/#havetermmetaindatabase","title":"haveTermMetaInDatabase","text":"

Signature: haveTermMetaInDatabase(int $term_id, string $meta_key, mixed $meta_value) : int

Inserts a term meta row in the database. Objects and array meta values will be serialized.

<?php\n$I->haveTermMetaInDatabase($fictionId, 'readers_count', 23);\n// Insert some meta that will be serialized.\n$I->haveTermMetaInDatabase($fictionId, 'flags', [3, 4, 89]);\n// Use a loop to insert one meta per row.\nforeach([3, 4, 89] as $value) {\n     $I->haveTermMetaInDatabase($fictionId, 'flag', $value);\n}\n
"},{"location":"modules/WPDb/#havetermrelationshipindatabase","title":"haveTermRelationshipInDatabase","text":"

Signature: haveTermRelationshipInDatabase(int $object_id, int $term_taxonomy_id, [int $term_order]) : void

Creates a term relationship in the database.

No check about the consistency of the insertion is made. E.g. a post could be assigned a term from a taxonomy that's not registered for that post type.

<?php\n// Assign the `fiction` term to a book.\n$I->haveTermRelationshipInDatabase($bookId, $fictionId);\n
"},{"location":"modules/WPDb/#havetransientindatabase","title":"haveTransientInDatabase","text":"

Signature: haveTransientInDatabase(string $transient, mixed $value) : int

Inserts a transient in the database.

If the value is an array or an object then the value will be serialized. Since the transients are set in the context of tests it's not possible to set an expiration directly.

<?php\n// Store an array in the `tweets` transient.\n$I->haveTransientInDatabase('tweets', $tweets);\n
"},{"location":"modules/WPDb/#haveusercapabilitiesindatabase","title":"haveUserCapabilitiesInDatabase","text":"

Signature: haveUserCapabilitiesInDatabase(int $userId, array|string $role) : array

Sets a user capabilities in the database.

<?php\n// Assign one user a role in a blog.\n$blogId = $I->haveBlogInDatabase('test');\n$editor = $I->haveUserInDatabase('luca', 'editor');\n$capsIds = $I->haveUserCapabilitiesInDatabase($editor, [$blogId => 'editor']);\n\n// Assign a user two roles in blog 1.\n$capsIds = $I->haveUserCapabilitiesInDatabase($userId, ['editor', 'subscriber']);\n\n// Assign one user different roles in different blogs.\n$capsIds = $I->haveUserCapabilitiesInDatabase($userId, [$blogId1 => 'editor', $blogId2 => 'author']);\n\n// Assign a user a role and an additional capability in blog 1.\n$I->haveUserCapabilitiesInDatabase($userId, ['editor' => true, 'edit_themes' => true]);\n\n// Assign a user a mix of roles and capabilities in different blogs.\n$capsIds = $I->haveUserCapabilitiesInDatabase(\n     $userId,\n     [\n         $blogId1 => ['editor' => true, 'edit_themes' => true],\n         $blogId2 => ['administrator' => true, 'edit_themes' => false]\n     ]\n);\n
"},{"location":"modules/WPDb/#haveuserindatabase","title":"haveUserInDatabase","text":"

Signature: haveUserInDatabase(string $user_login, [array|string $role], [array $overrides]) : int

Inserts a user and its meta in the database.

<?php\n// Create an editor user in blog 1 w/ specific email.\n$userId = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);\n\n// Create a subscriber user in blog 1.\n$subscriberId = $I->haveUserInDatabase('subscriber');\n\n// Create a user editor in blog 1, author in blog 2, administrator in blog 3.\n$userWithMeta = $I->haveUserInDatabase('luca',\n     [\n         1 => 'editor',\n         2 => 'author',\n         3 => 'administrator'\n     ], [\n         'user_email' => 'luca@example.org'\n         'meta' => ['a meta_key' => 'a_meta_value']\n     ]\n);\n\n// Create editor in blog 1 w/ `edit_themes` cap, author in blog 2, admin in blog 3 w/o `manage_options` cap.\n$userWithMeta = $I->haveUserInDatabase('luca',\n     [\n         1 => ['editor', 'edit_themes'],\n         2 => 'author',\n         3 => ['administrator' => true, 'manage_options' => false]\n     ]\n);\n\n// Create a user w/o role.\n$userId = $I->haveUserInDatabase('luca', '');\n
"},{"location":"modules/WPDb/#haveuserlevelsindatabase","title":"haveUserLevelsInDatabase","text":"

Signature: haveUserLevelsInDatabase(int $userId, array|string $role) : array

Sets the user access level meta in the database for a user.

<?php\n$userId = $I->haveUserInDatabase('luca', 'editor');\n$moreThanAnEditorLessThanAnAdmin = 8;\n$I->haveUserLevelsInDatabase($userId, $moreThanAnEditorLessThanAnAdmin);\n
"},{"location":"modules/WPDb/#haveusermetaindatabase","title":"haveUserMetaInDatabase","text":"

Signature: haveUserMetaInDatabase(int $userId, string $meta_key, mixed $meta_value) : array

Sets a user meta in the database.

<?php\n$userId = $I->haveUserInDatabase('luca', 'editor');\n$I->haveUserMetaInDatabase($userId, 'karma', 23);\n
"},{"location":"modules/WPDb/#importsql","title":"importSql","text":"

Signature: importSql(array $sql) : void

Loads a set SQL code lines in the current database.

<?php\n// Import a SQL string.\n$I->importSql([$sqlString]);\n// Import a set of SQL strings.\n$I->importSql($sqlStrings);\n// Import a prepared set of SQL strings.\n$preparedSqlStrings = array_map(function($line){\n    return str_replace('{{date}}', date('Y-m-d H:i:s'), $line);\n}, $sqlTemplate);\n$I->importSql($preparedSqlStrings);\n
"},{"location":"modules/WPDb/#importsqldumpfile","title":"importSqlDumpFile","text":"

Signature: importSqlDumpFile([?string $dumpFile]) : void

Import the SQL dump file if populate is enabled.

<?php\n// Import a dump file passing the absolute path.\n$I->importSqlDumpFile(codecept_data_dir('dumps/start.sql'));\n

Specifying a dump file that file will be imported.

"},{"location":"modules/WPDb/#performindatabase","title":"performInDatabase","text":"

Signature: performInDatabase($databaseKey, $actions) : void

Can be used with a callback if you don't want to change the current database in your test.

<?php\n$I->seeNumRecords(2, 'users');   //executed on default database\n$I->performInDatabase('db_books', function($I) {\n    $I->seeNumRecords(30, 'books');  //executed on db_books database\n});\n$I->seeNumRecords(2, 'users');  //executed on default database\n
List of actions can be pragmatically built using Codeception\\Util\\ActionSequence:

<?php\n$I->performInDatabase('db_books', ActionSequence::build()\n    ->seeNumRecords(30, 'books')\n);\n
Alternatively an array can be used:

<?php\n$I->performInDatabase('db_books', ['seeNumRecords' => [30, 'books']]);\n

Choose the syntax you like the most and use it,

Actions executed from array or ActionSequence will print debug output for actions, and adds an action name to exception on failure.

"},{"location":"modules/WPDb/#seeattachmentindatabase","title":"seeAttachmentInDatabase","text":"

Signature: seeAttachmentInDatabase(array $criteria) : void

Checks for an attachment in the database.

<?php\n$url = 'https://example.org/images/foo.png';\n$I->seeAttachmentInDatabase(['guid' => $url]);\n
"},{"location":"modules/WPDb/#seeblogindatabase","title":"seeBlogInDatabase","text":"

Signature: seeBlogInDatabase(array $criteria) : void

Checks for a blog in the blogs table.

<?php\n// Search for a blog by `blog_id`.\n$I->seeBlogInDatabase(['blog_id' => 23]);\n// Search for all blogs on a path.\n$I->seeBlogInDatabase(['path' => '/sub-path/']);\n
"},{"location":"modules/WPDb/#seecommentindatabase","title":"seeCommentInDatabase","text":"

Signature: seeCommentInDatabase(array $criteria) : void

Checks for a comment in the database.

Will look up the \"comments\" table.

<?php\n$I->seeCommentInDatabase(['comment_ID' => 23]);\n
"},{"location":"modules/WPDb/#seecommentmetaindatabase","title":"seeCommentMetaInDatabase","text":"

Signature: seeCommentMetaInDatabase(array $criteria) : void

Checks that a comment meta value is in the database. Will look up the \"commentmeta\" table.

<?php\n// Assert a specified meta for a comment exists.\n$I->seeCommentMetaInDatabase(['comment_ID' => $commentId, 'meta_key' => 'karma', 'meta_value' => 23]);\n// Assert the comment has at least one meta set.\n$I->seeCommentMetaInDatabase(['comment_ID' => $commentId]);\n
"},{"location":"modules/WPDb/#seeindatabase","title":"seeInDatabase","text":"

Signature: seeInDatabase(string $table, [array $criteria]) : void

"},{"location":"modules/WPDb/#seelinkindatabase","title":"seeLinkInDatabase","text":"

Signature: seeLinkInDatabase(array $criteria) : void

Checks for a link in the links table of the database.

<?php\n// Asserts a link exists by name.\n$I->seeLinkInDatabase(['link_name' => 'my-link']);\n// Asserts at least one link exists for the user.\n$I->seeLinkInDatabase(['link_owner' => $userId]);\n
"},{"location":"modules/WPDb/#seenumrecords","title":"seeNumRecords","text":"

Signature: seeNumRecords(int $expectedNumber, string $table, [array $criteria]) : void

Asserts that the given number of records were found in the database.

<?php\n$I->seeNumRecords(1, 'users', ['name' => 'davert'])\n
"},{"location":"modules/WPDb/#seeoptionindatabase","title":"seeOptionInDatabase","text":"

Signature: seeOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

Checks if an option is in the database for the current blog, either by criteria or by name and value.

If checking for an array or an object then the serialized version will be checked for.

<?php\n// Checks an option is in the database.\n$I->seeOptionInDatabase('tables_version');\n// Checks an option is in the database and has a specific value.\n$I->seeOptionInDatabase('tables_version', '1.0');\n$I->seeOptionInDatabase(['option_name' => 'tables_version', 'option_value' => 1.0']);\n
"},{"location":"modules/WPDb/#seepageindatabase","title":"seePageInDatabase","text":"

Signature: seePageInDatabase(array $criteria) : void

Checks for a page in the database.

<?php\n// Asserts a page with an exists in the database.\n$I->seePageInDatabase(['ID' => 23]);\n// Asserts a page with a slug and ID exists in the database.\n$I->seePageInDatabase(['post_title' => 'Test Page', 'ID' => 23]);\n
"},{"location":"modules/WPDb/#seepostindatabase","title":"seePostInDatabase","text":"

Signature: seePostInDatabase(array $criteria) : void

Checks for a post in the database.

<?php\n// Assert a post exists in the database.\n$I->seePostInDatabase(['ID' => 23]);\n// Assert a post with a slug and ID exists in the database.\n$I->seePostInDatabase(['post_content' => 'test content', 'ID' => 23]);\n
"},{"location":"modules/WPDb/#seepostmetaindatabase","title":"seePostMetaInDatabase","text":"

Signature: seePostMetaInDatabase(array $criteria) : void

Checks for a post meta value in the database for the current blog.

If the meta_value is an object or an array then the check will be made for serialized values.

<?php\n$postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']];\n$I->seePostMetaInDatabase(['post_id' => '$postId', 'meta_key' => 'foo']);\n
"},{"location":"modules/WPDb/#seepostwithtermindatabase","title":"seePostWithTermInDatabase","text":"

Signature: seePostWithTermInDatabase(int $post_id, int $term_taxonomy_id, [?int $term_order], [?string $taxonomy]) : void

Checks that a post to term relation exists in the database.

The method will check the \"term_relationships\" table.

<?php\n$fiction = $I->haveTermInDatabase('fiction', 'genre');\n$postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);\n$I->seePostWithTermInDatabase($postId, $fiction['term_taxonomy_id']);\n
"},{"location":"modules/WPDb/#seesiteoptionindatabase","title":"seeSiteOptionInDatabase","text":"

Signature: seeSiteOptionInDatabase(array|string $criteriaOrName, [mixed $value]) : void

Checks that a site option is in the database.

<?php\n// Check that the option is set in the database.\n$I->seeSiteOptionInDatabase('foo_count');\n// Check that the option is set and has a specific value.\n$I->seeSiteOptionInDatabase('foo_count', 23);\n
"},{"location":"modules/WPDb/#seesitesitetransientindatabase","title":"seeSiteSiteTransientInDatabase","text":"

Signature: seeSiteSiteTransientInDatabase(string $key, [mixed $value]) : void

Checks that a site option is in the database.

<?php\n// Check a transient exists.\n$I->seeSiteSiteTransientInDatabase('total_counts');\n// Check a transient exists and has a specific value.\n$I->seeSiteSiteTransientInDatabase('total_counts', 23);\n
"},{"location":"modules/WPDb/#seesitetransientindatabase","title":"seeSiteTransientInDatabase","text":"

Signature: seeSiteTransientInDatabase(string $transient, [mixed $value]) : void

Checks that a site transient is in the database.

<?php\n$I->haveSiteTransientInDatabase('foo', 23);\n$I->seeSiteTransientInDatabase('foo');\n$I->seeSiteTransientInDatabase('foo', 23);\n
"},{"location":"modules/WPDb/#seetableindatabase","title":"seeTableInDatabase","text":"

Signature: seeTableInDatabase(string $table) : void

Checks that a table is in the database.

<?php\n$options = $I->grabPrefixedTableNameFor('options');\n$I->seeTableInDatabase($options);\n
"},{"location":"modules/WPDb/#seetermindatabase","title":"seeTermInDatabase","text":"

Signature: seeTermInDatabase(array $criteria) : void

Checks for a term in the database. Looks up the terms and term_taxonomy prefixed tables.

<?php\n$I->seeTermInDatabase(['slug' => 'genre--fiction']);\n$I->seeTermInDatabase(['name' => 'Fiction', 'slug' => 'genre--fiction']);\n
"},{"location":"modules/WPDb/#seetermmetaindatabase","title":"seeTermMetaInDatabase","text":"

Signature: seeTermMetaInDatabase(array $criteria) : void

Checks for a term meta in the database.

<?php\nlist($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n$I->haveTermMetaInDatabase($termId, 'rating', 4);\n$I->seeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'rating', 'meta_value' => 4]);\n
"},{"location":"modules/WPDb/#seetermrelationshipindatabase","title":"seeTermRelationshipInDatabase","text":"

Signature: seeTermRelationshipInDatabase(array $criteria) : void

Checks for a term relationship in the database.

<?php\n$postId = $I->havePostInDatabase(['tax_input' => ['category' => 'one']]);\n$I->seeTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $oneTermTaxId]);\n
"},{"location":"modules/WPDb/#seetermtaxonomyindatabase","title":"seeTermTaxonomyInDatabase","text":"

Signature: seeTermTaxonomyInDatabase(array $criteria) : void

Checks for a taxonomy taxonomy in the database.

<?php\nlist($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n$I->seeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'genre']);\n
"},{"location":"modules/WPDb/#seetransientindatabase","title":"seeTransientInDatabase","text":"

Signature: seeTransientInDatabase(string $name, [mixed $value]) : void

Checks that a transient is in the database.

<?php\n$I->haveTransientInDatabase('foo', 23);\n$I->seeTransientInDatabase('foo');\n$I->seeTransientInDatabase('foo', 23);\n
"},{"location":"modules/WPDb/#seeuserindatabase","title":"seeUserInDatabase","text":"

Signature: seeUserInDatabase(array $criteria) : void

Checks that a user is in the database.

The method will check the \"users\" table.

<?php\n$I->seeUserInDatabase([\n    \"user_email\" => \"test@example.org\",\n    \"user_login\" => \"login name\"\n])\n
"},{"location":"modules/WPDb/#seeusermetaindatabase","title":"seeUserMetaInDatabase","text":"

Signature: seeUserMetaInDatabase(array $criteria) : void

Checks for a user meta value in the database.

<?php\n$I->seeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);\n
"},{"location":"modules/WPDb/#updateindatabase","title":"updateInDatabase","text":"

Signature: updateInDatabase(string $table, array $data, [array $criteria]) : void

Update an SQL record into a database.

<?php\n$I->updateInDatabase('users', array('isAdmin' => true), array('email' => 'miles@davis.com'));\n
"},{"location":"modules/WPDb/#useblog","title":"useBlog","text":"

Signature: useBlog([int $blogId]) : void

Sets the blog to be used.

This has nothing to do with WordPress switch_to_blog function, this code will affect the table prefixes used.

"},{"location":"modules/WPDb/#usemainblog","title":"useMainBlog","text":"

Signature: useMainBlog() : void

Sets the current blog to the main one (blog_id 1).

<?php\n// Switch to the blog with ID 23.\n$I->useBlog(23);\n// Switch back to the main blog.\n$I->useMainBlog();\n
"},{"location":"modules/WPDb/#usetheme","title":"useTheme","text":"

Signature: useTheme(string $stylesheet, [?string $template], [?string $themeName]) : void

Sets the current theme options.

<?php\n$I->useTheme('twentyseventeen');\n$I->useTheme('child-of-twentyseventeen', 'twentyseventeen');\n$I->useTheme('acme', 'acme', 'Acme Theme');\n

Read more in Codeception documentation for the Db module.

"},{"location":"modules/WPFilesystem/","title":"WPFilesystem","text":""},{"location":"modules/WPFilesystem/#wpfilesystem-module","title":"WPFilesystem module","text":"

Interact and make assertions on the WordPress file structure.

This module is used together with the WPDb module to manage the state of the WordPress installation in the context of end-to-end tests.

This module extends the Filesystem module from Codeception, you can reference to the Codeception documentation to find out more about the module configuration and usage.

This module should be with Cest and Cept test cases.

"},{"location":"modules/WPFilesystem/#configuration","title":"Configuration","text":"

wpRootFolder - required; the path to the WordPress installation root folder. This can be a relative path to the codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation directory is the directory that contains the wp-load.php file. themes - the path, relative to the path specified in the wpRootFolder parameter, to the themes directory. By default, it's /wp-content/themes. plugins - the path, relative to the path specified in the wpRootFolder parameter, to the plugins directory. By default, it's /wp-content/plugins. mu-plugins - the path, relative to the path specified in the wpRootFolder parameter, to the must-use plugins. By default, it's /wp-content/mu-plugins. directory. uploads - the path, relative to the path specified in the wpRootFolder parameter, to the uploads directory. By default, it's /wp-content/uploads.

The following is an example of the module configuration to run tests on the /var/wordpress site:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPFilesystem:\n      wpRootFolder: /var/wordpress\n      themes: wp-content/themes\n      plugins: wp-content/plugins\n      mu-plugins: wp-content/mu-plugins\n      uploads: wp-content/uploads\n

The following configuration uses dynamic configuration parameters to set the module configuration:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPFilesystem:\n      wpRootFolder: '%WP_ROOT_FOLDER%'\n
"},{"location":"modules/WPFilesystem/#methods","title":"Methods","text":"

The module provides the following methods:

"},{"location":"modules/WPFilesystem/#aminmupluginpath","title":"amInMuPluginPath","text":"

Signature: amInMuPluginPath(string $path) : void

Sets the current working folder to a folder in a mu-plugin.

$I->amInMuPluginPath('mu-plugin');\n
"},{"location":"modules/WPFilesystem/#aminpath","title":"amInPath","text":"

Signature: amInPath(string $path) : void

Enters a directory In local filesystem. Project root directory is used by default

"},{"location":"modules/WPFilesystem/#aminpluginpath","title":"amInPluginPath","text":"

Signature: amInPluginPath(string $path) : void

Sets the current working folder to a folder in a plugin.

$I->amInPluginPath('my-plugin');\n
"},{"location":"modules/WPFilesystem/#aminthemepath","title":"amInThemePath","text":"

Signature: amInThemePath(string $path) : void

Sets the current working folder to a folder in a theme.

$I->amInThemePath('my-theme');\n
"},{"location":"modules/WPFilesystem/#aminuploadspath","title":"amInUploadsPath","text":"

Signature: amInUploadsPath([?string $path]) : void

Enters, changing directory, to the uploads folder in the local filesystem.

<?php\n$I->amInUploadsPath('/logs');\n$I->seeFileFound('shop.log');\n
"},{"location":"modules/WPFilesystem/#assertdirectoryexists","title":"assertDirectoryExists","text":"

Signature: assertDirectoryExists(string $directory, [string $message]) : void

"},{"location":"modules/WPFilesystem/#cleandir","title":"cleanDir","text":"

Signature: cleanDir(string $dirname) : void

Erases directory contents

<?php\n$I->cleanDir('logs');\n
"},{"location":"modules/WPFilesystem/#cleanmuplugindir","title":"cleanMuPluginDir","text":"

Signature: cleanMuPluginDir(string $dir) : void

Cleans, emptying it, a folder in a mu-plugin folder.

$I->cleanMuPluginDir('mu-plugin1/foo');\n
"},{"location":"modules/WPFilesystem/#cleanplugindir","title":"cleanPluginDir","text":"

Signature: cleanPluginDir(string $dir) : void

Cleans, emptying it, a folder in a plugin folder.

$I->cleanPluginDir('my-plugin/foo');\n
"},{"location":"modules/WPFilesystem/#cleanthemedir","title":"cleanThemeDir","text":"

Signature: cleanThemeDir(string $dir) : void

Clears, emptying it, a folder in a theme folder.

$I->cleanThemeDir('my-theme/foo');\n
"},{"location":"modules/WPFilesystem/#cleanuploadsdir","title":"cleanUploadsDir","text":"

Signature: cleanUploadsDir([?string $dir], [DateTime|string|int|null $date]) : void

Clears a folder in the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

$I->cleanUploadsDir('some/folder');\n$I->cleanUploadsDir('some/folder', 'today');\n
"},{"location":"modules/WPFilesystem/#copydir","title":"copyDir","text":"

Signature: copyDir(string $src, string $dst) : void

Copies directory with all contents

<?php\n$I->copyDir('vendor','old_vendor');\n
"},{"location":"modules/WPFilesystem/#copydirtomuplugin","title":"copyDirToMuPlugin","text":"

Signature: copyDirToMuPlugin(string $src, string $pluginDst) : void

Copies a folder to a folder in a mu-plugin.

$I->copyDirToMuPlugin(codecept_data_dir('foo'), 'mu-plugin/foo');\n
"},{"location":"modules/WPFilesystem/#copydirtoplugin","title":"copyDirToPlugin","text":"

Signature: copyDirToPlugin(string $src, string $pluginDst) : void

Copies a folder to a folder in a plugin.

// Copy the 'foo' folder to the 'foo' folder in the plugin.\n$I->copyDirToPlugin(codecept_data_dir('foo'), 'my-plugin/foo');\n
"},{"location":"modules/WPFilesystem/#copydirtotheme","title":"copyDirToTheme","text":"

Signature: copyDirToTheme(string $src, string $themeDst) : void

Copies a folder in a theme folder.

$I->copyDirToTheme(codecept_data_dir('foo'), 'my-theme');\n
"},{"location":"modules/WPFilesystem/#copydirtouploads","title":"copyDirToUploads","text":"

Signature: copyDirToUploads(string $src, string $dst, [DateTime|string|int|null $date]) : void

Copies a folder to the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

$I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo');\n$I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo', 'today');\n
"},{"location":"modules/WPFilesystem/#deletedir","title":"deleteDir","text":"

Signature: deleteDir(string $dirname) : void

Deletes directory with all subdirectories

<?php\n$I->deleteDir('vendor');\n
"},{"location":"modules/WPFilesystem/#deletefile","title":"deleteFile","text":"

Signature: deleteFile(string $filename) : void

Deletes a file

<?php\n$I->deleteFile('composer.lock');\n
"},{"location":"modules/WPFilesystem/#deletemupluginfile","title":"deleteMuPluginFile","text":"

Signature: deleteMuPluginFile(string $file) : void

Deletes a file in a mu-plugin folder.

$I->deleteMuPluginFile('mu-plugin1/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#deletepluginfile","title":"deletePluginFile","text":"

Signature: deletePluginFile(string $file) : void

Deletes a file in a plugin folder.

$I->deletePluginFile('my-plugin/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#deletethemefile","title":"deleteThemeFile","text":"

Signature: deleteThemeFile(string $file) : void

Deletes a file in a theme folder.

$I->deleteThemeFile('my-theme/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#deletethisfile","title":"deleteThisFile","text":"

Signature: deleteThisFile() : void

Deletes a file

"},{"location":"modules/WPFilesystem/#deleteuploadeddir","title":"deleteUploadedDir","text":"

Signature: deleteUploadedDir(string $dir, [DateTime|string|int|null $date]) : void

Deletes a dir in the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

$I->deleteUploadedDir('folder');\n$I->deleteUploadedDir('folder', 'today');\n
"},{"location":"modules/WPFilesystem/#deleteuploadedfile","title":"deleteUploadedFile","text":"

Signature: deleteUploadedFile(string $file, [string|int|null $date]) : void

Deletes a file in the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

$I->deleteUploadedFile('some-file.txt');\n$I->deleteUploadedFile('some-file.txt', 'today');\n
"},{"location":"modules/WPFilesystem/#dontseefilefound","title":"dontSeeFileFound","text":"

Signature: dontSeeFileFound(string $filename, [string $path]) : void

Checks if file does not exist in path

"},{"location":"modules/WPFilesystem/#dontseeinmupluginfile","title":"dontSeeInMuPluginFile","text":"

Signature: dontSeeInMuPluginFile(string $file, string $contents) : void

Checks that a file in a mu-plugin folder does not contain a string.

$I->dontSeeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#dontseeinpluginfile","title":"dontSeeInPluginFile","text":"

Signature: dontSeeInPluginFile(string $file, string $contents) : void

Checks that a file in a plugin folder does not contain a string.

$I->dontSeeInPluginFile('my-plugin/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#dontseeinthemefile","title":"dontSeeInThemeFile","text":"

Signature: dontSeeInThemeFile(string $file, string $contents) : void

Checks that a file in a theme folder does not contain a string.

$I->dontSeeInThemeFile('my-theme/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#dontseeinthisfile","title":"dontSeeInThisFile","text":"

Signature: dontSeeInThisFile(string $text) : void

Checks If opened file doesn't contain text in it

<?php\n$I->openFile('composer.json');\n$I->dontSeeInThisFile('codeception/codeception');\n
"},{"location":"modules/WPFilesystem/#dontseeinuploadedfile","title":"dontSeeInUploadedFile","text":"

Signature: dontSeeInUploadedFile(string $file, string $contents, [string|int|null $date]) : void

Checks that a file in the uploads folder does contain a string.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

<?php\n$I->dontSeeInUploadedFile('some-file.txt', 'foo');\n$I->dontSeeInUploadedFile('some-file.txt','foo', 'today');\n
"},{"location":"modules/WPFilesystem/#dontseemupluginfilefound","title":"dontSeeMuPluginFileFound","text":"

Signature: dontSeeMuPluginFileFound(string $file) : void

Checks that a file is not found in a mu-plugin folder.

$I->dontSeeMuPluginFileFound('mu-plugin1/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#dontseepluginfilefound","title":"dontSeePluginFileFound","text":"

Signature: dontSeePluginFileFound(string $file) : void

Checks that a file is not found in a plugin folder.

$I->dontSeePluginFileFound('my-plugin/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#dontseethemefilefound","title":"dontSeeThemeFileFound","text":"

Signature: dontSeeThemeFileFound(string $file) : void

Checks that a file is not found in a theme folder.

$I->dontSeeThemeFileFound('my-theme/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#dontseeuploadedfilefound","title":"dontSeeUploadedFileFound","text":"

Signature: dontSeeUploadedFileFound(string $file, [string|int|null $date]) : void

Checks thata a file does not exist in the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

$I->dontSeeUploadedFileFound('some-file.txt');\n$I->dontSeeUploadedFileFound('some-file.txt','today');\n
"},{"location":"modules/WPFilesystem/#getbloguploadspath","title":"getBlogUploadsPath","text":"

Signature: getBlogUploadsPath(int $blogId, [string $file], [DateTimeImmutable|DateTime|string|null $date]) : string

Returns the absolute path to a blog uploads folder or file.

<?php\n$blogId = $I->haveBlogInDatabase('test');\n$testTodayUploads = $I->getBlogUploadsPath($blogId);\n$testLastMonthLogs = $I->getBlogUploadsPath($blogId, '/logs', '-1 month');\n
"},{"location":"modules/WPFilesystem/#getuploadspath","title":"getUploadsPath","text":"

Signature: getUploadsPath([string $file], [mixed $date]) : string

Returns the path to the specified uploads file of folder.

Not providing a value for $file and $date will return the uploads folder path.

<?php\n$todaysPath = $I->getUploadsPath();\n$lastWeek = $I->getUploadsPath('', '-1 week');\n
"},{"location":"modules/WPFilesystem/#getwprootfolder","title":"getWpRootFolder","text":"

Signature: getWpRootFolder() : string

Returns the absolute path to WordPress root folder without trailing slash.

<?php\n$rootFolder = $I->getWpRootFolder();\n$I->assertFileExists($rootFolder . 'wp-load.php');\n
"},{"location":"modules/WPFilesystem/#havemuplugin","title":"haveMuPlugin","text":"

Signature: haveMuPlugin(string $filename, string $code) : void

Creates a mu-plugin file, including plugin header, in the mu-plugins folder.

The code can not contain the opening '<?php' tag.

$code = 'echo \"Hello world!\"';\n$I->haveMuPlugin('foo-mu-plugin.php', $code);\n// Load the code from a file.\n$code = file_get_contents(codecept_data_dir('code/mu-plugin.php'));\n$I->haveMuPlugin('foo-mu-plugin.php', $code);\n
"},{"location":"modules/WPFilesystem/#haveplugin","title":"havePlugin","text":"

Signature: havePlugin(string $path, string $code) : void

Creates a plugin file, including plugin header, in the plugins folder.

The plugin is just created and not activated; the code can not contain the opening '<?php' tag.

$code = 'echo \"Hello world!\"';\n$I->havePlugin('foo/plugin.php', $code);\n// Load the code from a file.\n$code = file_get_contents(codecept_data_dir('code/plugin.php'));\n$I->havePlugin('foo/plugin.php', $code);\n
"},{"location":"modules/WPFilesystem/#havetheme","title":"haveTheme","text":"

Signature: haveTheme(string $folder, string $indexFileCode, [string $functionsFileCode]) : void

Creates a theme file structure, including theme style file and index, in the themes folder.

The theme is just created and not activated; the code can not contain the opening '<?php' tag.

$code = 'sayHi();';\n$functionsCode  = 'function sayHi(){echo \"Hello world\";};';\n$I->haveTheme('foo', $indexCode, $functionsCode);\n// Load the code from a file.\n$indexCode = file_get_contents(codecept_data_dir('code/index.php'));\n$functionsCode = file_get_contents(codecept_data_dir('code/functions.php'));\n$I->haveTheme('foo', $indexCode, $functionsCode);\n
"},{"location":"modules/WPFilesystem/#makeuploadsdir","title":"makeUploadsDir","text":"

Signature: makeUploadsDir(string $path) : string

Creates an empty folder in the WordPress installation uploads folder.

<?php\n$logsDir = $I->makeUploadsDir('logs/acme');\n
"},{"location":"modules/WPFilesystem/#openfile","title":"openFile","text":"

Signature: openFile(string $filename) : void

Opens a file and stores it's content.

Usage:

<?php\n$I->openFile('composer.json');\n$I->seeInThisFile('codeception/codeception');\n
"},{"location":"modules/WPFilesystem/#openuploadedfile","title":"openUploadedFile","text":"

Signature: openUploadedFile(string $filename, [DateTime|string|int|null $date]) : void

Opens a file in the the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

$I->openUploadedFile('some-file.txt');\n$I->openUploadedFile('some-file.txt', 'time');\n
"},{"location":"modules/WPFilesystem/#seefilecontentsequal","title":"seeFileContentsEqual","text":"

Signature: seeFileContentsEqual(string $text) : void

Checks the strict matching of file contents. Unlike seeInThisFile will fail if file has something more than expected lines. Better to use with HEREDOC strings. Matching is done after removing \"\\r\" chars from file content.

<?php\n$I->openFile('process.pid');\n$I->seeFileContentsEqual('3192');\n
"},{"location":"modules/WPFilesystem/#seefilefound","title":"seeFileFound","text":"

Signature: seeFileFound(string $filename, [string $path]) : void

Checks if file exists in path. Opens a file when it's exists

<?php\n$I->seeFileFound('UserModel.php','app/models');\n
"},{"location":"modules/WPFilesystem/#seeinmupluginfile","title":"seeInMuPluginFile","text":"

Signature: seeInMuPluginFile(string $file, string $contents) : void

Checks that a file in a mu-plugin folder contains a string.

$I->seeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#seeinpluginfile","title":"seeInPluginFile","text":"

Signature: seeInPluginFile(string $file, string $contents) : void

Checks that a file in a plugin folder contains a string.

$I->seeInPluginFile('my-plugin/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#seeinthemefile","title":"seeInThemeFile","text":"

Signature: seeInThemeFile(string $file, string $contents) : void

Checks that a file in a theme folder contains a string.

<?php\n$I->seeInThemeFile('my-theme/some-file.txt', 'foo');\n?>\n
"},{"location":"modules/WPFilesystem/#seeinthisfile","title":"seeInThisFile","text":"

Signature: seeInThisFile(string $text) : void

Checks If opened file has text in it.

Usage:

<?php\n$I->openFile('composer.json');\n$I->seeInThisFile('codeception/codeception');\n
"},{"location":"modules/WPFilesystem/#seeinuploadedfile","title":"seeInUploadedFile","text":"

Signature: seeInUploadedFile(string $file, string $contents, [string|int|null $date]) : void

Checks that a file in the uploads folder contains a string.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

<?php\n$I->seeInUploadedFile('some-file.txt', 'foo');\n$I->seeInUploadedFile('some-file.txt','foo', 'today');\n
"},{"location":"modules/WPFilesystem/#seemupluginfilefound","title":"seeMuPluginFileFound","text":"

Signature: seeMuPluginFileFound(string $file) : void

Checks that a file is found in a mu-plugin folder.

$I->seeMuPluginFileFound('mu-plugin1/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#seenumbernewlines","title":"seeNumberNewLines","text":"

Signature: seeNumberNewLines(int $number) : void

Checks If opened file has the number of new lines.

Usage:

<?php\n$I->openFile('composer.json');\n$I->seeNumberNewLines(5);\n
"},{"location":"modules/WPFilesystem/#seepluginfilefound","title":"seePluginFileFound","text":"

Signature: seePluginFileFound(string $file) : void

Checks that a file is found in a plugin folder.

$I->seePluginFileFound('my-plugin/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#seethemefilefound","title":"seeThemeFileFound","text":"

Signature: seeThemeFileFound(string $file) : void

Checks that a file is found in a theme folder.

$I->seeThemeFileFound('my-theme/some-file.txt');\n
"},{"location":"modules/WPFilesystem/#seethisfilematches","title":"seeThisFileMatches","text":"

Signature: seeThisFileMatches(string $regex) : void

Checks that contents of currently opened file matches $regex

"},{"location":"modules/WPFilesystem/#seeuploadedfilefound","title":"seeUploadedFileFound","text":"

Signature: seeUploadedFileFound(string $filename, [string|int|null $date]) : void

Checks if file exists in the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

<?php\n$I->seeUploadedFileFound('some-file.txt');\n$I->seeUploadedFileFound('some-file.txt','today');\n?>\n
"},{"location":"modules/WPFilesystem/#writetofile","title":"writeToFile","text":"

Signature: writeToFile(string $filename, string $contents) : void

Saves contents to file

"},{"location":"modules/WPFilesystem/#writetomupluginfile","title":"writeToMuPluginFile","text":"

Signature: writeToMuPluginFile(string $file, string $data) : void

Writes a file in a mu-plugin folder.

$I->writeToMuPluginFile('mu-plugin1/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#writetopluginfile","title":"writeToPluginFile","text":"

Signature: writeToPluginFile(string $file, string $data) : void

Writes a file in a plugin folder.

$I->writeToPluginFile('my-plugin/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#writetothemefile","title":"writeToThemeFile","text":"

Signature: writeToThemeFile(string $file, string $data) : void

Writes a string to a file in a theme folder.

$I->writeToThemeFile('my-theme/some-file.txt', 'foo');\n
"},{"location":"modules/WPFilesystem/#writetouploadedfile","title":"writeToUploadedFile","text":"

Signature: writeToUploadedFile(string $filename, string $data, [DateTime|string|int|null $date]) : string

Writes a string to a file in the the uploads folder.

The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

$I->writeToUploadedFile('some-file.txt', 'foo bar');\n$I->writeToUploadedFile('some-file.txt', 'foo bar', 'today');\n

Read more in Codeception documentation.

"},{"location":"modules/WPLoader/","title":"WPLoader","text":""},{"location":"modules/WPLoader/#wploader-module","title":"WPLoader module","text":"

A module to load WordPress and make its code available in tests.

Depending on the value of the loadOnly configuration parameter, the module will behave differently:

  • loadOnly: false - The module will load WordPress like the Core PHPUnit suite does to run integration tests in a controlled environment. Use the module in this mode with test cases generated using the generate:wpunit command.
  • loadOnly: true - The module will load WordPress to make it available in the context of tests. Use the module in this mode in Cest, Cept and Codeception unit test cases.
"},{"location":"modules/WPLoader/#configuration-with-loadonly-false","title":"Configuration with loadOnly: false","text":"

The module will load WordPress like the Core PHPUnit suite does to run integration tests in a controlled environment. Together with the test case generated by the generate:wpunit command the module will:

  • take care of running any test method in a database transaction rolled back after each test
  • manage and clean up the global environment and context between tests

When used in this mode, the module supports the following configuration parameters:

  • loadOnly - false to load WordPress and run tests in a controlled environment.
  • wpRootFolder - required; the path to the WordPress installation root folder. This can be a relative path to the codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation directory is the directory that contains the wp-load.php file.
  • dbUrl - required; the URL to the database to use to run tests. The URL must be in the form mysql://username:password@host:port/database to use a MySQL database, or in the form sqlite://path/to/database to use a SQLite database. Alternatively, you can use the dbName, dbUser, dbPassword, dbHost configuration parameters to specify the database connection details.
  • dump - the path to a database dump, or a set of database dumps, to load before running tests. The dump will be loaded only once, after the tests run.
  • tablePrefix - the database table prefix to use when loading WordPress, defaults to wp_.
  • multisite - a boolean value to indicate if WordPress should be loaded and initialized in multisite mode.
  • dbCharset - the database charset to use when loading WordPress.
  • dbCollate - the database collate to use when loading WordPress.
  • domain - the domain to use when loading WordPress. Equivalent to defining the WP_TESTS_DOMAIN constant.
  • adminEmail - the administrator email to use when loading WordPress. Equivalent to defining the WP_TESTS_EMAIL constant.
  • title - the site title to use when loading WordPress. Equivalent to defining the WP_TESTS_TITLE constant.
  • phpBinary - the path to the PHP binary to use to run tests. Defaults to the WP_PHP_BINARY constant.
  • language - the language to use when loading WordPress. Equivalent to defining the WPLANG constant.
  • configFile - a configuration file, or a set of configuration files, to load before the tests to further customize and control the WordPress testing environment.
  • pluginsFolder - the path to the plugins folder to use when loading WordPress. Equivalent to defining the WP_PLUGIN_DIR constant.
  • plugins - a list of plugins to activate and load in the WordPress installation. If the plugin is located in the WordPress installation plugins directory, then the plugin name can be specified using the directory/file.php format. If the plugin is located in an arbitrary path inside or outiside of the WordPress installation or project, then the plugin name must be specified either as an absolute path or as a relative path to the project root folder.
  • silentlyActivatePlugins - a list of plugins to activate silently, without firing their activation hooks. Depending on the plugin, a silent activation might cause the plugin to not work correctly. The list must be in the same format as the plugins parameter and plugin should be activated silently only if they are not working correctly during normal activation and are known to work correctly when activated silently. Plugin paths can be specified following the same format of the plugins parameter.
  • bootstrapActions - a list of actions or callables to call after WordPress is loaded and before the tests run.
  • theme - the theme to activate and load in the WordPress installation. The theme can be specified in slug format, e.g., twentytwentythree, to load it from the WordPress installation themes directory. Alternatively, the theme can be specified as an absolute or relative path to a theme folder, e.g., /home/themes/my-theme or vendor/acme/vendor-theme. To use both a parent and ha child theme from arbitrary absolute or relative paths, define the theme parameter as an array of theme paths, e.g., ['/home/themes/parent-theme', '.'].
  • AUTH_KEY - the AUTH_KEY constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • SECURE_AUTH_KEY - the SECURE_AUTH_KEY constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • LOGGED_IN_KEY - the LOGGED_IN_KEY constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • NONCE_KEY - the NONCE_KEY constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • AUTH_SALT - the AUTH_SALT constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • SECURE_AUTH_SALT - the SECURE_AUTH_SALT constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • LOGGED_IN_SALT - the LOGGED_IN_SALT constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • NONCE_SALT - the NONCE_SALT constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • AUTOMATIC_UPDATER_DISABLED - the AUTOMATIC_UPDATER_DISABLED constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • WP_HTTP_BLOCK_EXTERNAL - the WP_HTTP_BLOCK_EXTERNAL constant value to use when loading WordPress. If the wpRootFolder path points at a configured installation, containing the wp-config.php file, then the value of the constant in the configuration file will be used, else it will be randomly generated.
  • backupGlobals - a boolean value to indicate if the global environment should be backed up before each test. Defaults to true. The globals' backup involves serialization of the global state, plugins or themes that define classes developed to prevent serialization of the global state will cause the tests to fail. Set this parameter to false to disable the global environment backup, or use a more refined approach setting the backupGlobalsExcludeList parameter below. Note that a test case that is explicitly setting the backupGlobals property will override this configuration parameter.
  • backupGlobalsExcludeList - a list of global variables to exclude from the global environment backup. The list must be in the form of array, and it will be merged to the list of globals excluded by default.
  • backupStaticAttributes - a boolean value to indicate if static attributes of classes should be backed up before each test. Defaults to true. The static attributes' backup involves serialization of the global state, plugins or themes that define classes developed to prevent serialization of the global state will cause the tests to fail. Set this parameter to false to disable the static attributes backup, or use a more refined approanch setting the backupStaticAttributesExcludeList parameter below. Note that a test case that is explicitly setting the backupStaticAttributes property will override this configuration parameter.
  • backupStaticAttributesExcludeList - a list of classes to exclude from the static attributes backup. The list must be in the form of map from class names to the array of method names to exclude from the backup. See an example below.
  • skipInstall - a boolean value to indicate if the WordPress installation should be skipped between runs, when already installed. Defaults to false. During boot, the WPLoader module will re-install WordPress and activate, on top of the fresh installation, any plugin and theme specified in the plugins and theme configuration parameters: this can be a time-consuming operation. Set this parameter to true to run the WordPress installation once and just load it on the following runs. To force the installation to run again, rerun the suite using the WPLoader module using the --debug flag or delete the _wploader-state.sql file in the suite directory. This configuration parameter is ignored when the loadOnly parameter is set to true.
  • beStrictAboutWpdbConnectionId - a boolean value to indicate if the WPTestCase class should throw an exception if the database connection is closed during any setUpBeforeClass method; default is true.

This is an example of an integration suite configured to use the module:

actor: IntegrationTester\nbootstrap: _bootstrap.php\nmodules:\n  enabled:\n    - \\Helper\\Integration\n    - lucatume\\WPBrowser\\Module\\WPLoader:\n        wpRootFolder: /var/wordpress\n        dbUrl: mysql://root:root@mysql:3306/wordpress\n        tablePrefix: test_\n        domain: wordpress.test\n        adminEmail: admin@wordpress.test\n        title: 'Integration Tests'\n        plugins:\n          # This plugin will be loaded from the WordPress installation plugins directory.\n          - hello.php \n          # This plugin will be loaded from an arbitrary absolute path.\n          - /home/plugins/woocommerce/woocommerce.php \n          # This plugin will be loaded from an arbitrary relative path inside the project root folder.\n          - vendor/acme/project/plugin.php\n          # This plugin will be loaded from the project root folder.\n          - my-plugin.php\n        theme: twentytwentythree # Load the theme from the WordPress installation themes directory.\n

The following configuration uses dynamic configuration parameters to set the module configuration:

actor: IntegrationTester\nbootstrap: _bootstrap.php\nmodules:\n  enabled:\n    - \\Helper\\Integration\n    - lucatume\\WPBrowser\\Module\\WPLoader:\n        wpRootFolder: '%WP_ROOT_FOLDER%'\n        dbUrl: '%WP_DB_URL%'\n        tablePrefix: '%WP_TABLE_PREFIX%'\n        domain: '%WP_DOMAIN%'\n        adminEmail: '%WP_ADMIN_EMAIL%'\n        title: '%WP_TITLE%'\n        plugins:\n          - hello.php\n          - /home/plugins/woocommerce/woocommerce.php\n          - my-plugin.php\n          - vendor/acme/project/plugin.php\n        # Parent theme from the WordPress installation themes directory, child theme from absolute path.\n        theme: [twentytwentythree, /home/themes/my-theme]\n

The following example configuration uses a SQLite database and loads a database fixture before the tests run:

actor: IntegrationTester\nbootstrap: _bootstrap.php\nmodules:\n  enabled:\n    - \\Helper\\Integration\n    - lucatume\\WPBrowser\\Module\\WPLoader:\n        wpRootFolder: /var/wordpress\n        dbUrl: sqlite:///var/wordpress/wp-tests.sqlite\n        dump:\n          - tests/_data/products.sql\n          - tests/_data/users.sql\n          - tests/_data/orders.sql\n        tablePrefix: test_\n        domain: wordpress.test\n        adminEmail: admin@wordpress.test\n        title: 'Integration Tests'\n        plugins:\n          - hello.php\n          - woocommerce/woocommerce.php\n          - my-plugin/my-plugin.php\n        theme: \n          # Parent theme from relative path.\n          - vendor/acme/parent-theme\n          # Child theme from the current working directory.\n          - .\n

The follow example configuration prevents the backup of globals and static attributes in all the tests of the suite that are not explicitly overriding the backupGlobals and backupStaticAttributes properties:

actor: IntegrationTester\nbootstrap: _bootstrap.php\nmodules:\n  enabled:\n    - \\Helper\\Integration\n    - lucatume\\WPBrowser\\Module\\WPLoader:\n        wpRootFolder: /var/wordpress\n        dbUrl: sqlite:///var/wordpress/wp-tests.sqlite\n        dump:\n          - tests/_data/products.sql\n          - tests/_data/users.sql\n          - tests/_data/orders.sql\n        tablePrefix: test_\n        domain: wordpress.test\n        adminEmail: admin@wordpress.test\n        title: 'Integration Tests'\n        plugins:\n          - hello.php\n          - woocommerce/woocommerce.php\n          - my-plugin/my-plugin.php\n        theme: twentytwentythree\n        backupGlobals: false\n        backupStaticAttributes: false \n

The following configuration prevents the backup of some globals and static attributes:

actor: IntegrationTester\nbootstrap: _bootstrap.php\nmodules:\n  enabled:\n    - \\Helper\\Integration\n    - lucatume\\WPBrowser\\Module\\WPLoader:\n        wpRootFolder: /var/wordpress\n        dbUrl: sqlite:///var/wordpress/wp-tests.sqlite\n        dump:\n          - tests/_data/products.sql\n          - tests/_data/users.sql\n          - tests/_data/orders.sql\n        tablePrefix: test_\n        domain: wordpress.test\n        adminEmail: admin@wordpress.test\n        title: 'Integration Tests'\n        plugins:\n          - hello.php\n          - woocommerce/woocommerce.php\n          - my-plugin/my-plugin.php\n        theme: twentytwentythree\n        backupGlobalsExcludeList:\n          - my_plugin_will_explode_on_wakeup\n          - another_problematic_global\n        backupStaticAttributesExcludeList:\n          - MyPlugin\\MyClass:\n              - instance\n              - anotherStaticAttributeThatWillExplodeOnWakeup\n          - AnotherPlugin\\AnotherClass:\n              - instance\n              - yetAnotherStaticAttributeThatWillExplodeOnWakeup\n
"},{"location":"modules/WPLoader/#handling-a-custom-site-structure","title":"Handling a custom site structure","text":"

The setup process should just work for standard and non-standard WordPress installations alike.

Even if you're working on a site project using a custom file structure, e.g. Bedrock, you will be able to set up your site to run tests using the default configuration based on PHP built-in server, Chromedriver and SQLite database.

"},{"location":"modules/WPLoader/#configuration-with-loadonly-true","title":"Configuration with loadOnly: true","text":"

The module will load WordPress from the location specified by the wpRootFodler parameter, relying on the WPDb module to manage the database state.

When used in this mode, the module supports the following configuration parameters:

  • loadOnly - true to load WordPress and make it available in the context of tests.
  • wpRootFolder - required; the path to the WordPress installation root folder. This can be a relative path to the codeception root directory, or an absolute path to the WordPress installation directory. The WordPress installation directory is the directory that contains the wp-load.php file.
  • dbUrl - required; the URL to the database to use to run tests. The URL must be in the form mysql://username:password@host:port/database to use a MySQL database, or in the form sqlite://path/to/database to use a SQLite database. Alternatively, you can use the dbName, dbUser, dbPassword, dbHost configuration parameters to specify the database connection details.
  • domain - the domain to use when loading WordPress. Equivalent to defining the WP_TESTS_DOMAIN constant.

The following is an example of the module configuration to run end-to-end tests on the site served at http://localhost:8080 URL and served from the /var/wordpress directory:

actor: EndToEndTester\nbootstrap: _bootstrap.php\nmodules:\n  enabled:\n    - \\Helper\\Integration\n    - lucatume\\WPBrowser\\Module\\WPWebDriver:\n        url: 'http://localhost:8080'\n        adminUsername: 'admin'\n        adminPassword: 'password'\n        adminPath: '/wp-admin'\n        browser: chrome\n        host: 'localhost'\n        port: '4444'\n        path: '/'\n        window_size: false\n        capabilities:\n          \"goog:chromeOptions\":\n            args:\n              - \"--headless\"\n              - \"--disable-gpu\"\n              - \"--disable-dev-shm-usage\"\n              - \"--proxy-server='direct://'\"\n              - \"--proxy-bypass-list=*\"\n              - \"--no-sandbox\"\n    - lucatume\\WPBrowser\\Module\\WPDb:\n        dbUrl: 'mysql://root:password@localhost:3306/wordpress'\n        url: 'http://localhost:8080'\n        tablePrefix: 'wp_'\n        dump: 'tests/_data/dump.sql'\n        populate: true\n        cleanup: true\n        reconnect: false\n        urlReplacement: true\n        originalUrl: http://wordpress.test\n        waitlock: 10\n        createIfNotExists: true\n    - lucatume\\WPBrowser\\Module\\WPLoader:\n        loadOnly: true\n        wpRootFolder: /var/wordpress\n        dbUrl: 'mysql://root:password@localhost:3306/wordpress'\n        domain: wordpress.test\n
"},{"location":"modules/WPLoader/#methods","title":"Methods","text":"

The module provides the following methods:

"},{"location":"modules/WPLoader/#factory","title":"factory","text":"

Signature: factory() : lucatume\\WPBrowser\\Module\\WPLoader\\FactoryStore

Accessor method to get the object storing the factories for things. This method gives access to the same factories provided by the Core test suite.

"},{"location":"modules/WPLoader/#getcontentfolder","title":"getContentFolder","text":"

Signature: getContentFolder([string $path]) : string

Returns the absolute path to the WordPress content directory.

"},{"location":"modules/WPLoader/#getinstallation","title":"getInstallation","text":"

Signature: getInstallation() : lucatume\\WPBrowser\\WordPress\\Installation

"},{"location":"modules/WPLoader/#getpluginsfolder","title":"getPluginsFolder","text":"

Signature: getPluginsFolder([string $path]) : string

Returns the absolute path to the plugins directory.

The value will first look at the WP_PLUGIN_DIR constant, then the pluginsFolder configuration parameter and will, finally, look in the default path from the WordPress root directory.

"},{"location":"modules/WPLoader/#getthemesfolder","title":"getThemesFolder","text":"

Signature: getThemesFolder([string $path]) : string

Returns the absolute path to the themes directory.

"},{"location":"modules/WPLoader/#getwprootfolder","title":"getWpRootFolder","text":"

Signature: getWpRootFolder([?string $path]) : string

Returns the absolute path to the WordPress root folder or a path within it..

"},{"location":"modules/WPQueries/","title":"WPQueries","text":""},{"location":"modules/WPQueries/#wpqueries-module","title":"WPQueries module","text":"

This module provides assertions for WordPress queries.

This module can be used in any test context where the global $wpdb variable is defined, this usually means in any suite where the WPLoader module is used.

"},{"location":"modules/WPQueries/#configuration","title":"Configuration","text":"

The method does not require configuration.

"},{"location":"modules/WPQueries/#methods","title":"Methods","text":"

The module provides the following methods:

"},{"location":"modules/WPQueries/#assertcountqueries","title":"assertCountQueries","text":"

Signature: assertCountQueries(int $n, [string $message]) : void

Asserts that n queries have been made.

<?php\n$posts = $this->factory()->post->create_many(3);\n$cachedUsers = $this->factory()->user->create_many(2);\n$nonCachedUsers = $this->factory()->user->create_many(2);\nforeach($cachedUsers as $userId){\n     wp_cache_set('page-posts-for-user-' . $userId, $posts, 'acme');\n}\n// Run the same query as different users\nforeach(array_merge($cachedUsers, $nonCachedUsers) as $userId){\n     $pagePosts = $plugin->getPagePostsForUser($userId);\n}\n$I->assertCountQueries(2, 'A query should be made for each user missing cached posts.')\n
"},{"location":"modules/WPQueries/#assertnotqueries","title":"assertNotQueries","text":"

Signature: assertNotQueries([string $message]) : void

Asserts that no queries were made.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$posts = $this->factory()->post->create_many(3);\nwp_cache_set('page-posts', $posts, 'acme');\n$pagePosts = $plugin->getPagePosts();\n$I->assertNotQueries('Queries should not be made if the cache is set.')\n
"},{"location":"modules/WPQueries/#assertnotqueriesbyaction","title":"assertNotQueriesByAction","text":"

Signature: assertNotQueriesByAction(string $action, [string $message]) : void

Asserts that no queries were made as a consequence of the specified action.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_action( 'edit_post', function($postId){\n        $count = get_option('acme_title_updates_count');\n        update_option('acme_title_updates_count', ++$count);\n} );\nwp_delete_post($bookId);\n$this->assertNotQueriesByAction('edit_post');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbyfilter","title":"assertNotQueriesByFilter","text":"

Signature: assertNotQueriesByFilter(string $filter, [string $message]) : void

Asserts that no queries were made as a consequence of the specified filter.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_filter('the_title', function($title, $postId){\n     $post = get_post($postId);\n     if($post->post_type !== 'book'){\n         return $title;\n     }\n     $new = get_option('acme_new_prefix');\n     return \"{$new} - \" . $title;\n});\n$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);\n$this->assertNotQueriesByFilter('the_title');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbyfunction","title":"assertNotQueriesByFunction","text":"

Signature: assertNotQueriesByFunction(string $function, [string $message]) : void

Asserts that no queries were made by the specified function.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$this->assertEmpty(Acme\\get_orphaned_posts());\nAcme\\delete_orphaned_posts();\n$this->assertNotQueriesByFunction('Acme\\delete_orphaned_posts');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbymethod","title":"assertNotQueriesByMethod","text":"

Signature: assertNotQueriesByMethod(string $class, string $method, [string $message]) : void

Asserts that no queries have been made by the specified class method.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$options = new Acme\\Options();\n$options->update('adsSource', 'not-a-real-url.org');\n$I->assertNotQueriesByMethod('Acme\\Options', 'update');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbystatement","title":"assertNotQueriesByStatement","text":"

Signature: assertNotQueriesByStatement(string $statement, [string $message]) : void

Asserts that no queries have been made by the specified class method.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$bookRepository = new Acme\\BookRepository();\n$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);\n$this->assertNotQueriesByStatement('INSERT', 'Deferred write should happen on __destruct');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbystatementandaction","title":"assertNotQueriesByStatementAndAction","text":"

Signature: assertNotQueriesByStatementAndAction(string $statement, string $action, [string $message]) : void

Asserts that no queries were made as a consequence of the specified action containing the SQL query.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_action( 'edit_post', function($postId){\n        $count = get_option('acme_title_updates_count');\n        update_option('acme_title_updates_count', ++$count);\n} );\nwp_delete_post($bookId);\n$this->assertNotQueriesByStatementAndAction('DELETE', 'delete_post');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbystatementandfilter","title":"assertNotQueriesByStatementAndFilter","text":"

Signature: assertNotQueriesByStatementAndFilter(string $statement, string $filter, [string $message]) : void

Asserts that no queries were made as a consequence of the specified filter containing the specified SQL query.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_filter('the_title', function($title, $postId){\n     $post = get_post($postId);\n     if($post->post_type !== 'book'){\n         return $title;\n     }\n     $new = get_option('acme_new_prefix');\n     return \"{$new} - \" . $title;\n});\n$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);\n$this->assertNotQueriesByStatementAndFilter('SELECT', 'the_title');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbystatementandfunction","title":"assertNotQueriesByStatementAndFunction","text":"

Signature: assertNotQueriesByStatementAndFunction(string $statement, string $function, [string $message]) : void

Asserts that no queries were made by the specified function starting with the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nwp_insert_post(['ID' => $bookId, 'post_title' => 'The Call of the Wild']);\n$this->assertNotQueriesByStatementAndFunction('INSERT', 'wp_insert_post');\n$this->assertQueriesByStatementAndFunction('UPDATE', 'wp_insert_post');\n
"},{"location":"modules/WPQueries/#assertnotqueriesbystatementandmethod","title":"assertNotQueriesByStatementAndMethod","text":"

Signature: assertNotQueriesByStatementAndMethod(string $statement, string $class, string $method, [string $message]) : void

Asserts that no queries were made by the specified class method starting with the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nAcme\\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();\n$this->assertQueriesByStatementAndMethod('INSERT', Acme\\BookRepository::class, 'commit');\n
"},{"location":"modules/WPQueries/#assertqueries","title":"assertQueries","text":"

Signature: assertQueries([string $message]) : void

Asserts that at least one query was made during the test.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nwp_cache_delete('page-posts', 'acme');\n$pagePosts = $plugin->getPagePosts();\n$I->assertQueries('Queries should be made to set the cache.')\n
"},{"location":"modules/WPQueries/#assertqueriesbyaction","title":"assertQueriesByAction","text":"

Signature: assertQueriesByAction(string $action, [string $message]) : void

Asserts that at least one query was made as a consequence of the specified action.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_action( 'edit_post', function($postId){\n        $count = get_option('acme_title_updates_count');\n        update_option('acme_title_updates_count', ++$count);\n} );\nwp_update_post(['ID' => $bookId, 'post_title' => 'New Title']);\n$this->assertQueriesByAction('edit_post');\n
"},{"location":"modules/WPQueries/#assertqueriesbyfilter","title":"assertQueriesByFilter","text":"

Signature: assertQueriesByFilter(string $filter, [string $message]) : void

Asserts that at least one query was made as a consequence of the specified filter.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_filter('the_title', function($title, $postId){\n     $post = get_post($postId);\n     if($post->post_type !== 'book'){\n         return $title;\n     }\n     $new = get_option('acme_new_prefix');\n     return \"{$new} - \" . $title;\n});\n$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);\n$this->assertQueriesByFilter('the_title');\n
"},{"location":"modules/WPQueries/#assertqueriesbyfunction","title":"assertQueriesByFunction","text":"

Signature: assertQueriesByFunction(string $function, [string $message]) : void

Asserts that queries were made by the specified function.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nacme_clean_queue();\n$this->assertQueriesByFunction('acme_clean_queue');\n
"},{"location":"modules/WPQueries/#assertqueriesbymethod","title":"assertQueriesByMethod","text":"

Signature: assertQueriesByMethod(string $class, string $method, [string $message]) : void

Asserts that at least one query has been made by the specified class method.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$options = new Acme\\Options();\n$options->update('showAds', false);\n$I->assertQueriesByMethod('Acme\\Options', 'update');\n
"},{"location":"modules/WPQueries/#assertqueriesbystatement","title":"assertQueriesByStatement","text":"

Signature: assertQueriesByStatement(string $statement, [string $message]) : void

Asserts that at least a query starting with the specified statement was made.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nwp_cache_flush();\ncached_get_posts($args);\n$I->assertQueriesByStatement('SELECT');\n
"},{"location":"modules/WPQueries/#assertqueriesbystatementandaction","title":"assertQueriesByStatementAndAction","text":"

Signature: assertQueriesByStatementAndAction(string $statement, string $action, [string $message]) : void

Asserts that at least one query was made as a consequence of the specified action containing the SQL query.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_action( 'edit_post', function($postId){\n        $count = get_option('acme_title_updates_count');\n        update_option('acme_title_updates_count', ++$count);\n} );\nwp_update_post(['ID' => $bookId, 'post_title' => 'New']);\n$this->assertQueriesByStatementAndAction('UPDATE', 'edit_post');\n
"},{"location":"modules/WPQueries/#assertqueriesbystatementandfilter","title":"assertQueriesByStatementAndFilter","text":"

Signature: assertQueriesByStatementAndFilter(string $statement, string $filter, [string $message]) : void

Asserts that at least one query was made as a consequence of the specified filter containing the SQL query.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_filter('the_title', function($title, $postId){\n     $post = get_post($postId);\n     if($post->post_type !== 'book'){\n         return $title;\n     }\n     $new = get_option('acme_new_prefix');\n     return \"{$new} - \" . $title;\n});\n$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);\n$this->assertQueriesByStatementAndFilter('SELECT', 'the_title');\n
"},{"location":"modules/WPQueries/#assertqueriesbystatementandfunction","title":"assertQueriesByStatementAndFunction","text":"

Signature: assertQueriesByStatementAndFunction(string $statement, string $function, [string $message]) : void

Asserts that queries were made by the specified function starting with the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nwp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);\n$this->assertQueriesByStatementAndFunction('INSERT', 'wp_insert_post');\n
"},{"location":"modules/WPQueries/#assertqueriesbystatementandmethod","title":"assertQueriesByStatementAndMethod","text":"

Signature: assertQueriesByStatementAndMethod(string $statement, string $class, string $method, [string $message]) : void

Asserts that queries were made by the specified class method starting with the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nAcme\\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();\n$this->assertQueriesByStatementAndMethod('UPDATE', Acme\\BookRepository::class, 'commit');\n
"},{"location":"modules/WPQueries/#assertqueriescountbyaction","title":"assertQueriesCountByAction","text":"

Signature: assertQueriesCountByAction(int $n, string $action, [string $message]) : void

Asserts that n queries were made as a consequence of the specified action.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_action( 'edit_post', function($postId){\n        $count = get_option('acme_title_updates_count');\n        update_option('acme_title_updates_count', ++$count);\n} );\nwp_update_post(['ID' => $bookOneId, 'post_title' => 'One']);\nwp_update_post(['ID' => $bookTwoId, 'post_title' => 'Two']);\nwp_update_post(['ID' => $bookThreeId, 'post_title' => 'Three']);\n$this->assertQueriesCountByAction(3, 'edit_post');\n
"},{"location":"modules/WPQueries/#assertqueriescountbyfilter","title":"assertQueriesCountByFilter","text":"

Signature: assertQueriesCountByFilter(int $n, string $filter, [string $message]) : void

Asserts that n queries were made as a consequence of the specified filter.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_filter('the_title', function($title, $postId){\n     $post = get_post($postId);\n     if($post->post_type !== 'book'){\n         return $title;\n     }\n     $new = get_option('acme_new_prefix');\n     return \"{$new} - \" . $title;\n});\n$title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);\n$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);\n$title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);\n$this->assertQueriesCountByFilter(2, 'the_title');\n
"},{"location":"modules/WPQueries/#assertqueriescountbyfunction","title":"assertQueriesCountByFunction","text":"

Signature: assertQueriesCountByFunction(int $n, string $function, [string $message]) : void

Asserts that n queries were made by the specified function.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$this->assertCount(3, Acme\\get_orphaned_posts());\nAcme\\delete_orphaned_posts();\n$this->assertQueriesCountByFunction(3, 'Acme\\delete_orphaned_posts');\n
"},{"location":"modules/WPQueries/#assertqueriescountbymethod","title":"assertQueriesCountByMethod","text":"

Signature: assertQueriesCountByMethod(int $n, string $class, string $method, [string $message]) : void

Asserts that n queries have been made by the specified class method.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$bookRepository = new Acme\\BookRepository();\n$repository->where('ID', 23)->commit('title', 'Peter Pan');\n$repository->where('ID', 89)->commit('title', 'Moby-dick');\n$repository->where('ID', 2389)->commit('title', 'The call of the wild');\n$this->assertQueriesCountByMethod(3, 'Acme\\BookRepository', 'commit');\n
"},{"location":"modules/WPQueries/#assertqueriescountbystatement","title":"assertQueriesCountByStatement","text":"

Signature: assertQueriesCountByStatement(int $n, string $statement, [string $message]) : void

Asserts that n queries starting with the specified statement were made.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\n$bookRepository = new Acme\\BookRepository();\n$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);\n$repository->where('ID', 89)->set('title', 'Moby-dick', $deferred = true);\n$repository->where('ID', 2389)->set('title', 'The call of the wild', $deferred = false);\n$this->assertQueriesCountByStatement(1, 'INSERT', 'Deferred write should happen on __destruct');\n
"},{"location":"modules/WPQueries/#assertqueriescountbystatementandaction","title":"assertQueriesCountByStatementAndAction","text":"

Signature: assertQueriesCountByStatementAndAction(int $n, string $statement, string $action, [string $message]) : void

Asserts that n queries were made as a consequence of the specified action containing the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_action( 'edit_post', function($postId){\n        $count = get_option('acme_title_updates_count');\n        update_option('acme_title_updates_count', ++$count);\n} );\nwp_delete_post($bookOneId);\nwp_delete_post($bookTwoId);\nwp_update_post(['ID' => $bookThreeId, 'post_title' => 'New']);\n$this->assertQueriesCountByStatementAndAction(2, 'DELETE', 'delete_post');\n$this->assertQueriesCountByStatementAndAction(1, 'INSERT', 'edit_post');\n
"},{"location":"modules/WPQueries/#assertqueriescountbystatementandfilter","title":"assertQueriesCountByStatementAndFilter","text":"

Signature: assertQueriesCountByStatementAndFilter(int $n, string $statement, string $filter, [string $message]) : void

Asserts that n queries were made as a consequence of the specified filter containing the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nadd_filter('the_title', function($title, $postId){\n     $post = get_post($postId);\n     if($post->post_type !== 'book'){\n         return $title;\n     }\n     $new = get_option('acme_new_prefix');\n     return \"{$new} - \" . $title;\n});\n// Warm up the cache.\n$title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);\n// Cache is warmed up now.\n$title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);\n$title = apply_filters('the_title', get_post($bookThreeId)->post_title, $bookThreeId);\n$this->assertQueriesCountByStatementAndFilter(1, 'SELECT', 'the_title');\n
"},{"location":"modules/WPQueries/#assertqueriescountbystatementandfunction","title":"assertQueriesCountByStatementAndFunction","text":"

Signature: assertQueriesCountByStatementAndFunction(int $n, string $statement, string $function, [string $message]) : void

Asserts that n queries were made by the specified function starting with the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nwp_insert_post(['post_type' => 'book', 'post_title' => 'The Call of the Wild']);\nwp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);\nwp_insert_post(['post_type' => 'book', 'post_title' => 'The Chocolate Factory']);\n$this->assertQueriesCountByStatementAndFunction(3, 'INSERT', 'wp_insert_post');\n
"},{"location":"modules/WPQueries/#assertqueriescountbystatementandmethod","title":"assertQueriesCountByStatementAndMethod","text":"

Signature: assertQueriesCountByStatementAndMethod(int $n, string $statement, string $class, string $method, [string $message]) : void

Asserts that n queries were made by the specified class method starting with the specified SQL statement.

Queries generated by setUp, tearDown and factory methods are excluded by default.

<?php\nAcme\\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();\nAcme\\BookRepository::new(['title' => 'Moby-Dick'])->commit();\nAcme\\BookRepository::new(['title' => 'The Call of the Wild'])->commit();\n$this->assertQueriesCountByStatementAndMethod(3, 'INSERT', Acme\\BookRepository::class, 'commit');\n
"},{"location":"modules/WPQueries/#countqueries","title":"countQueries","text":"

Signature: countQueries([?wpdb $wpdb]) : int

Returns the current number of queries. Set-up and tear-down queries performed by the test case are filtered out.

<?php\n// In a WPTestCase, using the global $wpdb object.\n$queriesCount = $this->queries()->countQueries();\n// In a WPTestCase, using a custom $wpdb object.\n$queriesCount = $this->queries()->countQueries($customWdbb);\n
"},{"location":"modules/WPQueries/#getqueries","title":"getQueries","text":"

Signature: getQueries([?wpdb $wpdb]) : array

Returns the queries currently performed by the global database object or the specified one. Set-up and tear-down queries performed by the test case are filtered out.

<?php\n// In a WPTestCase, using the global $wpdb object.\n$queries = $this->queries()->getQueries();\n// In a WPTestCase, using a custom $wpdb object.\n$queries = $this->queries()->getQueries($customWdbb);\n
"},{"location":"modules/WPWebDriver/","title":"WPWebDriver","text":""},{"location":"modules/WPWebDriver/#wpwebdriver-module","title":"WPWebDriver module","text":"

This module drives a browser using a solution like Selenium or Chromedriver to simulate user interactions with the WordPress project.

The module has full Javascript support, differently from the WPBrowser module, and can be used to test sites that use Javascript to render the page or to make assertions that require Javascript support.

The method extends the Codeception WebDriver module and is used in the context of Cest and Cept test cases.

"},{"location":"modules/WPWebDriver/#configuration","title":"Configuration","text":"
  • browser - the browser to use; e.g. 'chrome'
  • host - the host to use; e.g. 'localhost'. This is the host of the Selenium server or the Chromedriver server.
  • port - the port to use; e.g. '4444'. This is the port of the Selenium server or the Chromedriver server.
  • path - the path to use; e.g. '/wd/hub' or '/'. Use '/' for Chrome.
  • url - required; the start URL of your WordPress project.
  • adminUsername - required; the site administrator username to use in actions like loginAsAdmin.
  • adminPassword - required; the site administrator password to use in actions like loginAsAdmin.
  • adminPath - the path to the WordPress admin directory; defaults to /wp-admin.

More configuration options, and their explanation, are available in the Codeception WebDriver module documentation.

The following is an example of the module configuration to run tests on thehttp://localhost:8080 site:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPBrowser:\n      url: 'http://localhost:8080'\n      adminUsername: 'admin'\n      adminPassword: 'password'\n      adminPath: '/wp-admin'\n      browser: chrome\n      host: 'localhost'\n      port: '4444'\n      path: '/'\n      window_size: false\n      capabilities:\n        \"goog:chromeOptions\":\n          args:\n            - \"--headless\"\n            - \"--disable-gpu\"\n            - \"--disable-dev-shm-usage\"\n            - \"--proxy-server='direct://'\"\n            - \"--proxy-bypass-list=*\"\n            - \"--no-sandbox\"\n

The following configuration uses dynamic configuration parameters to set the module configuration:

modules:\n  enabled:\n    lucatume\\WPBrowser\\Module\\WPBrowser:\n      url: 'http://localhost:8080'\n      adminUsername: 'admin'\n      adminPassword: 'password'\n      adminPath: '/wp-admin'\n      browser: chrome\n      host: '%CHROME_HOST%'\n      port: '%CHROME_PORT%'\n      path: '/'\n      window_size: `1920,1080`\n      capabilities:\n        \"goog:chromeOptions\":\n          args:\n            - \"--headless\"\n            - \"--disable-gpu\"\n            - \"--disable-dev-shm-usage\"\n            - \"--proxy-server='direct://'\"\n            - \"--proxy-bypass-list=*\"\n            - \"--no-sandbox\"\n

Furthermore, the above configuration will not run Chrome in headless mode: the browser window will be visible.

"},{"location":"modules/WPWebDriver/#methods","title":"Methods","text":"

The module provides the following methods:

"},{"location":"modules/WPWebDriver/#acceptpopup","title":"acceptPopup","text":"

Signature: acceptPopup() : void

Accepts the active JavaScript native popup window, as created by window.alert|window.confirm|window.prompt. Don't confuse popups with modal windows, as created by various libraries.

"},{"location":"modules/WPWebDriver/#activateplugin","title":"activatePlugin","text":"

Signature: activatePlugin(array|string $pluginSlug) : void

In the plugin administration screen activates one or more plugins clicking the \"Activate\" link.

The method will not handle authentication and navigation to the plugins administration page.

<?php\n// Activate a plugin.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->activatePlugin('hello-dolly');\n// Activate a list of plugins.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->activatePlugin(['hello-dolly','another-plugin']);\n
"},{"location":"modules/WPWebDriver/#activatetheme","title":"activateTheme","text":"

Signature: activateTheme(string $slug) : void

Activates a theme.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPWebDriver/#ameditingpostwithid","title":"amEditingPostWithId","text":"

Signature: amEditingPostWithId(int $id) : void

Go to the admin page to edit the post with the specified ID.

The method will not handle authentication the admin area.

<?php\n$I->loginAsAdmin();\n$postId = $I->havePostInDatabase();\n$I->amEditingPostWithId($postId);\n$I->fillField('post_title', 'Post title');\n
"},{"location":"modules/WPWebDriver/#ameditinguserwithid","title":"amEditingUserWithId","text":"

Signature: amEditingUserWithId(int $id) : void

Go to the admin page to edit the user with the specified ID.

The method will not handle authentication the admin area.

<?php\n$I->loginAsAdmin();\n$userId = $I->haveUserInDatabase('luca', 'editor');\n$I->amEditingUserWithId($userId);\n$I->fillField('email', 'new@example.net');\n
"},{"location":"modules/WPWebDriver/#amonadminajaxpage","title":"amOnAdminAjaxPage","text":"

Signature: amOnAdminAjaxPage([array|string|null $queryVars]) : void

Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.

The method will not handle authentication, nonces or authorization.

<?php\n$I->amOnAdminAjaxPage(['action' => 'my-action', 'data' => ['id' => 23], 'nonce' => $nonce]);\n
"},{"location":"modules/WPWebDriver/#amonadminpage","title":"amOnAdminPage","text":"

Signature: amOnAdminPage(string $page) : void

Go to a page in the admininstration area of the site.

This method will not handle authentication to the administration area.

<?php\n$I->loginAs('user', 'password');\n// Go to the plugins management screen.\n$I->amOnAdminPage('/plugins.php');\n
"},{"location":"modules/WPWebDriver/#amoncronpage","title":"amOnCronPage","text":"

Signature: amOnCronPage([array|string|null $queryVars]) : void

Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

<?php\n// Triggers the cron job with an optional query argument.\n$I->amOnCronPage('/?some-query-var=some-value');\n
"},{"location":"modules/WPWebDriver/#amonpage","title":"amOnPage","text":"

Signature: amOnPage($page) : void

"},{"location":"modules/WPWebDriver/#amonpagespage","title":"amOnPagesPage","text":"

Signature: amOnPagesPage() : void

Go the \"Pages\" administration screen.

The method will not handle authentication.

<?php\n$I->loginAsAdmin();\n$I->amOnPagesPage();\n$I->see('Add New');\n
"},{"location":"modules/WPWebDriver/#amonpluginspage","title":"amOnPluginsPage","text":"

Signature: amOnPluginsPage() : void

Go to the plugins administration screen.

The method will not handle authentication.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->activatePlugin('hello-dolly');\n
"},{"location":"modules/WPWebDriver/#amonsubdomain","title":"amOnSubdomain","text":"

Signature: amOnSubdomain(string $subdomain) : void

"},{"location":"modules/WPWebDriver/#amonthemespage","title":"amOnThemesPage","text":"

Signature: amOnThemesPage() : void

Moves to the themes administration page.

"},{"location":"modules/WPWebDriver/#amonurl","title":"amOnUrl","text":"

Signature: amOnUrl($url) : void

"},{"location":"modules/WPWebDriver/#appendfield","title":"appendField","text":"

Signature: appendField($field, string $value) : void

Append the given text to the given element. Can also add a selection to a select box.

<?php\n$I->appendField('#mySelectbox', 'SelectValue');\n$I->appendField('#myTextField', 'appended');\n
"},{"location":"modules/WPWebDriver/#attachfile","title":"attachFile","text":"

Signature: attachFile($field, string $filename) : void

"},{"location":"modules/WPWebDriver/#cancelpopup","title":"cancelPopup","text":"

Signature: cancelPopup() : void

Dismisses the active JavaScript popup, as created by window.alert, window.confirm, or window.prompt.

"},{"location":"modules/WPWebDriver/#checkoption","title":"checkOption","text":"

Signature: checkOption($option) : void

"},{"location":"modules/WPWebDriver/#clearfield","title":"clearField","text":"

Signature: clearField($field) : void

Clears given field which isn't empty.

<?php\n$I->clearField('#username');\n
"},{"location":"modules/WPWebDriver/#click","title":"click","text":"

Signature: click($link, [$context]) : void

"},{"location":"modules/WPWebDriver/#clickwithleftbutton","title":"clickWithLeftButton","text":"

Signature: clickWithLeftButton([$cssOrXPath], [?int $offsetX], [?int $offsetY]) : void

Performs click with the left mouse button on an element. If the first parameter null then the offset is relative to the actual mouse position. If the second and third parameters are given, then the mouse is moved to an offset of the element's top-left corner. Otherwise, the mouse is moved to the center of the element.

<?php\n$I->clickWithLeftButton(['css' => '.checkout']);\n$I->clickWithLeftButton(null, 20, 50);\n$I->clickWithLeftButton(['css' => '.checkout'], 20, 50);\n
"},{"location":"modules/WPWebDriver/#clickwithrightbutton","title":"clickWithRightButton","text":"

Signature: clickWithRightButton([$cssOrXPath], [?int $offsetX], [?int $offsetY]) : void

Performs contextual click with the right mouse button on an element. If the first parameter null then the offset is relative to the actual mouse position. If the second and third parameters are given, then the mouse is moved to an offset of the element's top-left corner. Otherwise, the mouse is moved to the center of the element.

<?php\n$I->clickWithRightButton(['css' => '.checkout']);\n$I->clickWithRightButton(null, 20, 50);\n$I->clickWithRightButton(['css' => '.checkout'], 20, 50);\n
"},{"location":"modules/WPWebDriver/#closetab","title":"closeTab","text":"

Signature: closeTab() : void

Closes current browser tab and switches to previous active tab.

<?php\n$I->closeTab();\n
"},{"location":"modules/WPWebDriver/#deactivateplugin","title":"deactivatePlugin","text":"

Signature: deactivatePlugin(array|string $pluginSlug) : void

In the plugin administration screen deactivate a plugin clicking the \"Deactivate\" link.

The method will not handle authentication and navigation to the plugins administration page.

<?php\n// Deactivate one plugin.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->deactivatePlugin('hello-dolly');\n// Deactivate a list of plugins.\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->deactivatePlugin(['hello-dolly', 'my-plugin']);\n
"},{"location":"modules/WPWebDriver/#debugwebdriverlogs","title":"debugWebDriverLogs","text":"

Signature: debugWebDriverLogs([?Codeception\\TestInterface $test]) : void

Print out latest Selenium Logs in debug mode

"},{"location":"modules/WPWebDriver/#deletesessionsnapshot","title":"deleteSessionSnapshot","text":"

Signature: deleteSessionSnapshot($name) : void

"},{"location":"modules/WPWebDriver/#dontsee","title":"dontSee","text":"

Signature: dontSee($text, [$selector]) : void

"},{"location":"modules/WPWebDriver/#dontseecheckboxischecked","title":"dontSeeCheckboxIsChecked","text":"

Signature: dontSeeCheckboxIsChecked($checkbox) : void

"},{"location":"modules/WPWebDriver/#dontseecookie","title":"dontSeeCookie","text":"

Signature: dontSeeCookie($cookie, [array $params], [bool $showDebug]) : void

"},{"location":"modules/WPWebDriver/#dontseecurrenturlequals","title":"dontSeeCurrentUrlEquals","text":"

Signature: dontSeeCurrentUrlEquals(string $uri) : void

"},{"location":"modules/WPWebDriver/#dontseecurrenturlmatches","title":"dontSeeCurrentUrlMatches","text":"

Signature: dontSeeCurrentUrlMatches(string $uri) : void

"},{"location":"modules/WPWebDriver/#dontseeelement","title":"dontSeeElement","text":"

Signature: dontSeeElement($selector, [array $attributes]) : void

"},{"location":"modules/WPWebDriver/#dontseeelementindom","title":"dontSeeElementInDOM","text":"

Signature: dontSeeElementInDOM($selector, [array $attributes]) : void

Opposite of seeElementInDOM.

"},{"location":"modules/WPWebDriver/#dontseeincurrenturl","title":"dontSeeInCurrentUrl","text":"

Signature: dontSeeInCurrentUrl(string $uri) : void

"},{"location":"modules/WPWebDriver/#dontseeinfield","title":"dontSeeInField","text":"

Signature: dontSeeInField($field, $value) : void

"},{"location":"modules/WPWebDriver/#dontseeinformfields","title":"dontSeeInFormFields","text":"

Signature: dontSeeInFormFields($formSelector, array $params) : void

"},{"location":"modules/WPWebDriver/#dontseeinpagesource","title":"dontSeeInPageSource","text":"

Signature: dontSeeInPageSource(string $text) : void

Checks that the page source doesn't contain the given string.

"},{"location":"modules/WPWebDriver/#dontseeinpopup","title":"dontSeeInPopup","text":"

Signature: dontSeeInPopup(string $text) : void

Checks that the active JavaScript popup, as created by window.alert|window.confirm|window.prompt, does NOT contain the given string.

"},{"location":"modules/WPWebDriver/#dontseeinsource","title":"dontSeeInSource","text":"

Signature: dontSeeInSource($raw) : void

"},{"location":"modules/WPWebDriver/#dontseeintitle","title":"dontSeeInTitle","text":"

Signature: dontSeeInTitle($title) : void

"},{"location":"modules/WPWebDriver/#dontseelink","title":"dontSeeLink","text":"

Signature: dontSeeLink(string $text, [string $url]) : void

"},{"location":"modules/WPWebDriver/#dontseeoptionisselected","title":"dontSeeOptionIsSelected","text":"

Signature: dontSeeOptionIsSelected($selector, $optionText) : void

"},{"location":"modules/WPWebDriver/#dontseeplugininstalled","title":"dontSeePluginInstalled","text":"

Signature: dontSeePluginInstalled(string $pluginSlug) : void

Assert a plugin is not installed in the plugins administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->dontSeePluginInstalled('my-plugin');\n
"},{"location":"modules/WPWebDriver/#doubleclick","title":"doubleClick","text":"

Signature: doubleClick($cssOrXPath) : void

Performs a double click on an element matched by CSS or XPath.

"},{"location":"modules/WPWebDriver/#draganddrop","title":"dragAndDrop","text":"

Signature: dragAndDrop($source, $target) : void

Performs a simple mouse drag-and-drop operation.

<?php\n$I->dragAndDrop('#drag', '#drop');\n
"},{"location":"modules/WPWebDriver/#executeasyncjs","title":"executeAsyncJS","text":"

Signature: executeAsyncJS(string $script, [array $arguments]) : void

Executes asynchronous JavaScript. A callback should be executed by JavaScript to exit from a script. Callback is passed as a last element in arguments array. Additional arguments can be passed as array in second parameter.

// wait for 1200 milliseconds my running `setTimeout`\n* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');\n\n$seconds = 1200; // or seconds are passed as argument\n$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);\n
"},{"location":"modules/WPWebDriver/#executeinselenium","title":"executeInSelenium","text":"

Signature: executeInSelenium(Closure $function) : void

Low-level API method. If Codeception commands are not enough, this allows you to use Selenium WebDriver methods directly:

$I->executeInSelenium(function(\\Facebook\\WebDriver\\Remote\\RemoteWebDriver $webdriver) {\n  $webdriver->get('https://google.com');\n});\n

This runs in the context of the RemoteWebDriver class. Try not to use this command on a regular basis. If Codeception lacks a feature you need, please implement it and submit a patch.

"},{"location":"modules/WPWebDriver/#executejs","title":"executeJS","text":"

Signature: executeJS(string $script, [array $arguments]) : void

Executes custom JavaScript.

This example uses jQuery to get a value and assigns that value to a PHP variable:

<?php\n$myVar = $I->executeJS('return $(\"#myField\").val()');\n\n// additional arguments can be passed as array\n// Example shows `Hello World` alert:\n$I->executeJS(\"window.alert(arguments[0])\", ['Hello world']);\n
"},{"location":"modules/WPWebDriver/#fillfield","title":"fillField","text":"

Signature: fillField($field, $value) : void

"},{"location":"modules/WPWebDriver/#grabactivetheme","title":"grabActiveTheme","text":"

Signature: grabActiveTheme() : ?string

Returns the slug of the currently active themes.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPWebDriver/#grabattributefrom","title":"grabAttributeFrom","text":"

Signature: grabAttributeFrom($cssOrXpath, $attribute) : ?string

"},{"location":"modules/WPWebDriver/#grabavailablethemes","title":"grabAvailableThemes","text":"

Signature: grabAvailableThemes([string $classes]) : array

Returns the list of available themes.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPWebDriver/#grabcookie","title":"grabCookie","text":"

Signature: grabCookie($cookie, [array $params]) : mixed

"},{"location":"modules/WPWebDriver/#grabcookieswithpattern","title":"grabCookiesWithPattern","text":"

Signature: grabCookiesWithPattern(string $cookiePattern) : ?array

Returns all the cookies whose name matches a regex pattern.

<?php\n$I->loginAs('customer','password');\n$I->amOnPage('/shop');\n$cartCookies = $I->grabCookiesWithPattern(\"#^shop_cart\\\\.*#\");\n
"},{"location":"modules/WPWebDriver/#grabfromcurrenturl","title":"grabFromCurrentUrl","text":"

Signature: grabFromCurrentUrl([$uri]) : mixed

"},{"location":"modules/WPWebDriver/#grabfullurl","title":"grabFullUrl","text":"

Signature: grabFullUrl() : string

Grabs the current page full URL including the query vars.

<?php\n$today = date('Y-m-d');\n$I->amOnPage('/concerts?date=' . $today);\n$I->assertRegExp('#\\\\/concerts$#', $I->grabFullUrl());\n
"},{"location":"modules/WPWebDriver/#grabmultiple","title":"grabMultiple","text":"

Signature: grabMultiple($cssOrXpath, [$attribute]) : array

"},{"location":"modules/WPWebDriver/#grabpagesource","title":"grabPageSource","text":"

Signature: grabPageSource() : string

Grabs current page source code.

"},{"location":"modules/WPWebDriver/#grabtextfrom","title":"grabTextFrom","text":"

Signature: grabTextFrom($cssOrXPathOrRegex) : mixed

"},{"location":"modules/WPWebDriver/#grabvaluefrom","title":"grabValueFrom","text":"

Signature: grabValueFrom($field) : ?string

"},{"location":"modules/WPWebDriver/#grabwordpresstestcookie","title":"grabWordPressTestCookie","text":"

Signature: grabWordPressTestCookie([?string $name]) : ?Symfony\\Component\\BrowserKit\\Cookie

Returns WordPress default test cookie object if present.

<?php\n// Grab the default WordPress test cookie.\n$wpTestCookie = $I->grabWordPressTestCookie();\n// Grab a customized version of the test cookie.\n$myTestCookie = $I->grabWordPressTestCookie('my_test_cookie');\n
"},{"location":"modules/WPWebDriver/#loadsessionsnapshot","title":"loadSessionSnapshot","text":"

Signature: loadSessionSnapshot($name, [bool $showDebug]) : bool

"},{"location":"modules/WPWebDriver/#logout","title":"logOut","text":"

Signature: logOut([string|bool $redirectTo]) : void

Navigate to the default WordPress logout page and click the logout link.

<?php\n// Log out using the `wp-login.php` form and return to the current page.\n$I->logOut(true);\n// Log out using the `wp-login.php` form and remain there.\n$I->logOut(false);\n// Log out using the `wp-login.php` form and move to another page.\n$I->logOut('/some-other-page');\n
"},{"location":"modules/WPWebDriver/#loginas","title":"loginAs","text":"

Signature: loginAs(string $username, string $password, [int $timeout], [int $maxAttempts]) : void

Login as the specified user.

The method will not follow redirection, after the login, to any page. Depending on the driven browser the login might be \"too fast\" and the server might have not replied with valid cookies yet; in that case the method will re-attempt the login to obtain the cookies.

<?php\n$I->loginAs('user', 'password');\n$I->amOnAdminPage('/');\n$I->see('Dashboard');\n
"},{"location":"modules/WPWebDriver/#loginasadmin","title":"loginAsAdmin","text":"

Signature: loginAsAdmin([int $timeout], [int $maxAttempts]) : void

Login as the administrator user using the credentials specified in the module configuration.

The method will not follow redirection, after the login, to any page.

<?php\n$I->loginAsAdmin();\n$I->amOnAdminPage('/');\n$I->see('Dashboard');\n
"},{"location":"modules/WPWebDriver/#makeelementscreenshot","title":"makeElementScreenshot","text":"

Signature: makeElementScreenshot($selector, [?string $name]) : void

Takes a screenshot of an element of the current window and saves it to tests/_output/debug.

<?php\n$I->amOnPage('/user/edit');\n$I->makeElementScreenshot('#dialog', 'edit_page');\n// saved to: tests/_output/debug/edit_page.png\n$I->makeElementScreenshot('#dialog');\n// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png\n
"},{"location":"modules/WPWebDriver/#makehtmlsnapshot","title":"makeHtmlSnapshot","text":"

Signature: makeHtmlSnapshot([?string $name]) : void

"},{"location":"modules/WPWebDriver/#makescreenshot","title":"makeScreenshot","text":"

Signature: makeScreenshot([?string $name]) : void

Takes a screenshot of the current window and saves it to tests/_output/debug.

<?php\n$I->amOnPage('/user/edit');\n$I->makeScreenshot('edit_page');\n// saved to: tests/_output/debug/edit_page.png\n$I->makeScreenshot();\n// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png\n
"},{"location":"modules/WPWebDriver/#maximizewindow","title":"maximizeWindow","text":"

Signature: maximizeWindow() : void

Maximizes the current window.

"},{"location":"modules/WPWebDriver/#moveback","title":"moveBack","text":"

Signature: moveBack() : void

Moves back in history.

"},{"location":"modules/WPWebDriver/#moveforward","title":"moveForward","text":"

Signature: moveForward() : void

Moves forward in history.

"},{"location":"modules/WPWebDriver/#movemouseover","title":"moveMouseOver","text":"

Signature: moveMouseOver([$cssOrXPath], [?int $offsetX], [?int $offsetY]) : void

Move mouse over the first element matched by the given locator. If the first parameter null then the page is used. If the second and third parameters are given, then the mouse is moved to an offset of the element's top-left corner. Otherwise, the mouse is moved to the center of the element.

<?php\n$I->moveMouseOver(['css' => '.checkout']);\n$I->moveMouseOver(null, 20, 50);\n$I->moveMouseOver(['css' => '.checkout'], 20, 50);\n
"},{"location":"modules/WPWebDriver/#opennewtab","title":"openNewTab","text":"

Signature: openNewTab() : void

Opens a new browser tab and switches to it.

<?php\n$I->openNewTab();\n
The tab is opened with JavaScript's window.open(), which means: * Some ad-blockers might restrict it. * The sessionStorage is copied to the new tab (contrary to a tab that was manually opened by the user)

"},{"location":"modules/WPWebDriver/#performon","title":"performOn","text":"

Signature: performOn($element, $actions, [int $timeout]) : void

Waits for element and runs a sequence of actions inside its context. Actions can be defined with array, callback, or Codeception\\Util\\ActionSequence instance.

Actions as array are recommended for simple to combine \"waitForElement\" with assertions; waitForElement($el) and see('text', $el) can be simplified to:

<?php\n$I->performOn($el, ['see' => 'text']);\n

List of actions can be pragmatically build using Codeception\\Util\\ActionSequence:

<?php\n$I->performOn('.model', ActionSequence::build()\n    ->see('Warning')\n    ->see('Are you sure you want to delete this?')\n    ->click('Yes')\n);\n

Actions executed from array or ActionSequence will print debug output for actions, and adds an action name to exception on failure.

Whenever you need to define more actions a callback can be used. A WebDriver module is passed for argument:

<?php\n$I->performOn('.rememberMe', function (WebDriver $I) {\n     $I->see('Remember me next time');\n     $I->seeElement('#LoginForm_rememberMe');\n     $I->dontSee('Login');\n});\n

In 3rd argument you can set number a seconds to wait for element to appear

"},{"location":"modules/WPWebDriver/#presskey","title":"pressKey","text":"

Signature: pressKey($element, [...$chars]) : void

Presses the given key on the given element. To specify a character and modifier (e.g. Ctrl, Alt, Shift, Meta), pass an array for $char with the modifier as the first element and the character as the second. For special keys, use the constants from Facebook\\WebDriver\\WebDriverKeys.

<?php\n// <input id=\"page\" value=\"old\" />\n$I->pressKey('#page','a'); // => olda\n$I->pressKey('#page',array('ctrl','a'),'new'); //=> new\n$I->pressKey('#page',array('shift','111'),'1','x'); //=> old!!!1x\n$I->pressKey('descendant-or-self::*[@id='page']','u'); //=> oldu\n$I->pressKey('#name', array('ctrl', 'a'), \\Facebook\\WebDriver\\WebDriverKeys::DELETE); //=>''\n
"},{"location":"modules/WPWebDriver/#reloadpage","title":"reloadPage","text":"

Signature: reloadPage() : void

Reloads the current page.

"},{"location":"modules/WPWebDriver/#resetcookie","title":"resetCookie","text":"

Signature: resetCookie($cookie, [array $params], [bool $showDebug]) : void

"},{"location":"modules/WPWebDriver/#resizewindow","title":"resizeWindow","text":"

Signature: resizeWindow(int $width, int $height) : void

Resize the current window.

<?php\n$I->resizeWindow(800, 600);\n
"},{"location":"modules/WPWebDriver/#savesessionsnapshot","title":"saveSessionSnapshot","text":"

Signature: saveSessionSnapshot($name) : void

"},{"location":"modules/WPWebDriver/#scrollto","title":"scrollTo","text":"

Signature: scrollTo($selector, [?int $offsetX], [?int $offsetY]) : void

Move to the middle of the given element matched by the given locator. Extra shift, calculated from the top-left corner of the element, can be set by passing $offsetX and $offsetY parameters.

<?php\n$I->scrollTo(['css' => '.checkout'], 20, 50);\n
"},{"location":"modules/WPWebDriver/#see","title":"see","text":"

Signature: see($text, [$selector]) : void

"},{"location":"modules/WPWebDriver/#seecheckboxischecked","title":"seeCheckboxIsChecked","text":"

Signature: seeCheckboxIsChecked($checkbox) : void

"},{"location":"modules/WPWebDriver/#seecookie","title":"seeCookie","text":"

Signature: seeCookie($cookie, [array $params], [bool $showDebug]) : void

"},{"location":"modules/WPWebDriver/#seecurrenturlequals","title":"seeCurrentUrlEquals","text":"

Signature: seeCurrentUrlEquals(string $uri) : void

"},{"location":"modules/WPWebDriver/#seecurrenturlmatches","title":"seeCurrentUrlMatches","text":"

Signature: seeCurrentUrlMatches(string $uri) : void

"},{"location":"modules/WPWebDriver/#seeelement","title":"seeElement","text":"

Signature: seeElement($selector, [array $attributes]) : void

"},{"location":"modules/WPWebDriver/#seeelementindom","title":"seeElementInDOM","text":"

Signature: seeElementInDOM($selector, [array $attributes]) : void

Checks that the given element exists on the page, even it is invisible.

<?php\n$I->seeElementInDOM('//form/input[type=hidden]');\n
"},{"location":"modules/WPWebDriver/#seeerrormessage","title":"seeErrorMessage","text":"

Signature: seeErrorMessage([array|string $classes]) : void

In an administration screen look for an error admin notice.

The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

<?php\n$I->loginAsAdmin()\n$I->amOnAdminPage('/');\n$I->seeErrorMessage('.my-plugin');\n
"},{"location":"modules/WPWebDriver/#seeincurrenturl","title":"seeInCurrentUrl","text":"

Signature: seeInCurrentUrl(string $uri) : void

"},{"location":"modules/WPWebDriver/#seeinfield","title":"seeInField","text":"

Signature: seeInField($field, $value) : void

"},{"location":"modules/WPWebDriver/#seeinformfields","title":"seeInFormFields","text":"

Signature: seeInFormFields($formSelector, array $params) : void

"},{"location":"modules/WPWebDriver/#seeinpagesource","title":"seeInPageSource","text":"

Signature: seeInPageSource(string $text) : void

Checks that the page source contains the given string.

<?php\n$I->seeInPageSource('<link rel=\"apple-touch-icon\"');\n
"},{"location":"modules/WPWebDriver/#seeinpopup","title":"seeInPopup","text":"

Signature: seeInPopup(string $text) : void

Checks that the active JavaScript popup, as created by window.alert|window.confirm|window.prompt, contains the given string.

"},{"location":"modules/WPWebDriver/#seeinsource","title":"seeInSource","text":"

Signature: seeInSource($raw) : void

"},{"location":"modules/WPWebDriver/#seeintitle","title":"seeInTitle","text":"

Signature: seeInTitle($title) : void

"},{"location":"modules/WPWebDriver/#seelink","title":"seeLink","text":"

Signature: seeLink(string $text, [?string $url]) : void

"},{"location":"modules/WPWebDriver/#seemessage","title":"seeMessage","text":"

Signature: seeMessage([array|string $classes]) : void

In an administration screen look for an admin notice.

The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

<?php\n$I->loginAsAdmin()\n$I->amOnAdminPage('/');\n$I->seeMessage('.missing-api-token.my-plugin');\n
"},{"location":"modules/WPWebDriver/#seenumberofelements","title":"seeNumberOfElements","text":"

Signature: seeNumberOfElements($selector, $expected) : void

"},{"location":"modules/WPWebDriver/#seenumberofelementsindom","title":"seeNumberOfElementsInDOM","text":"

Signature: seeNumberOfElementsInDOM($selector, $expected) : void

"},{"location":"modules/WPWebDriver/#seenumberoftabs","title":"seeNumberOfTabs","text":"

Signature: seeNumberOfTabs(int $number) : void

Checks current number of opened tabs

<?php\n$I->seeNumberOfTabs(2);\n
"},{"location":"modules/WPWebDriver/#seeoptionisselected","title":"seeOptionIsSelected","text":"

Signature: seeOptionIsSelected($selector, $optionText) : void

"},{"location":"modules/WPWebDriver/#seepluginactivated","title":"seePluginActivated","text":"

Signature: seePluginActivated(string $pluginSlug) : void

Assert a plugin is activated in the plugin administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->seePluginActivated('my-plugin');\n
"},{"location":"modules/WPWebDriver/#seeplugindeactivated","title":"seePluginDeactivated","text":"

Signature: seePluginDeactivated(string $pluginSlug) : void

Assert a plugin is not activated in the plugins administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->seePluginDeactivated('my-plugin');\n
"},{"location":"modules/WPWebDriver/#seeplugininstalled","title":"seePluginInstalled","text":"

Signature: seePluginInstalled(string $pluginSlug) : void

Assert a plugin is installed, no matter its activation status, in the plugin administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

<?php\n$I->loginAsAdmin();\n$I->amOnPluginsPage();\n$I->seePluginInstalled('my-plugin');\n
"},{"location":"modules/WPWebDriver/#seethemeactivated","title":"seeThemeActivated","text":"

Signature: seeThemeActivated(string $slug) : void

Verifies that a theme is active.

The method will not handle authentication and navigation to the themes administration page.

"},{"location":"modules/WPWebDriver/#seewpdiepage","title":"seeWpDiePage","text":"

Signature: seeWpDiePage() : void

Checks that the current page is one generated by the wp_die function.

The method will try to identify the page based on the default WordPress die page HTML attributes.

<?php\n$I->loginAs('user', 'password');\n$I->amOnAdminPage('/forbidden');\n$I->seeWpDiePage();\n
"},{"location":"modules/WPWebDriver/#selectoption","title":"selectOption","text":"

Signature: selectOption($select, $option) : void

"},{"location":"modules/WPWebDriver/#setcookie","title":"setCookie","text":"

Signature: setCookie($name, $value, [array $params], [$showDebug]) : void

"},{"location":"modules/WPWebDriver/#submitform","title":"submitForm","text":"

Signature: submitForm($selector, array $params, [$button]) : void

Submits the given form on the page, optionally with the given form values. Give the form fields values as an array. Note that hidden fields can't be accessed.

Skipped fields will be filled by their values from the page. You don't need to click the 'Submit' button afterwards. This command itself triggers the request to form's action.

You can optionally specify what button's value to include in the request with the last parameter as an alternative to explicitly setting its value in the second parameter, as button values are not otherwise included in the request.

Examples:

<?php\n$I->submitForm('#login', [\n    'login' => 'davert',\n    'password' => '123456'\n]);\n// or\n$I->submitForm('#login', [\n    'login' => 'davert',\n    'password' => '123456'\n], 'submitButtonName');\n

For example, given this sample \"Sign Up\" form:

<form action=\"/sign_up\">\n    Login:\n    <input type=\"text\" name=\"user[login]\" /><br/>\n    Password:\n    <input type=\"password\" name=\"user[password]\" /><br/>\n    Do you agree to our terms?\n    <input type=\"checkbox\" name=\"user[agree]\" /><br/>\n    Select pricing plan:\n    <select name=\"plan\">\n        <option value=\"1\">Free</option>\n        <option value=\"2\" selected=\"selected\">Paid</option>\n    </select>\n    <input type=\"submit\" name=\"submitButton\" value=\"Submit\" />\n</form>\n

You could write the following to submit it:

<?php\n$I->submitForm(\n    '#userForm',\n    [\n        'user[login]' => 'Davert',\n        'user[password]' => '123456',\n        'user[agree]' => true\n    ],\n    'submitButton'\n);\n
Note that \"2\" will be the submitted value for the \"plan\" field, as it is the selected option.

Also note that this differs from PhpBrowser, in that 'user' => [ 'login' => 'Davert' ] is not supported at the moment. Named array keys must be included in the name as above.

Pair this with seeInFormFields for quick testing magic.

<?php\n$form = [\n     'field1' => 'value',\n     'field2' => 'another value',\n     'checkbox1' => true,\n     // ...\n];\n$I->submitForm('//form[@id=my-form]', $form, 'submitButton');\n// $I->amOnPage('/path/to/form-page') may be needed\n$I->seeInFormFields('//form[@id=my-form]', $form);\n

Parameter values must be set to arrays for multiple input fields of the same name, or multi-select combo boxes. For checkboxes, either the string value can be used, or boolean values which will be replaced by the checkbox's value in the DOM.

<?php\n$I->submitForm('#my-form', [\n     'field1' => 'value',\n     'checkbox' => [\n         'value of first checkbox',\n         'value of second checkbox',\n     ],\n     'otherCheckboxes' => [\n         true,\n         false,\n         false,\n     ],\n     'multiselect' => [\n         'first option value',\n         'second option value',\n     ]\n]);\n

Mixing string and boolean values for a checkbox's value is not supported and may produce unexpected results.

Field names ending in \"[]\" must be passed without the trailing square bracket characters, and must contain an array for its value. This allows submitting multiple values with the same name, consider:

<?php\n$I->submitForm('#my-form', [\n    'field[]' => 'value',\n    'field[]' => 'another value', // 'field[]' is already a defined key\n]);\n

The solution is to pass an array value:

<?php\n// this way both values are submitted\n$I->submitForm('#my-form', [\n    'field' => [\n        'value',\n        'another value',\n    ]\n]);\n

The $button parameter can be either a string, an array or an instance of Facebook\\WebDriver\\WebDriverBy. When it is a string, the button will be found by its \"name\" attribute. If $button is an array then it will be treated as a strict selector and a WebDriverBy will be used verbatim.

For example, given the following HTML:

<input type=\"submit\" name=\"submitButton\" value=\"Submit\" />\n

$button could be any one of the following: - 'submitButton' - ['name' => 'submitButton'] - WebDriverBy::name('submitButton')

"},{"location":"modules/WPWebDriver/#switchtoframe","title":"switchToFrame","text":"

Signature: switchToFrame([?string $locator]) : void

Switch to another frame on the page.

Example:

<frame name=\"another_frame\" id=\"fr1\" src=\"https://example.com\">\n

<?php\n# switch to frame by name\n$I->switchToFrame(\"another_frame\");\n# switch to frame by CSS or XPath\n$I->switchToFrame(\"#fr1\");\n# switch to parent page\n$I->switchToFrame();\n
"},{"location":"modules/WPWebDriver/#switchtoiframe","title":"switchToIFrame","text":"

Signature: switchToIFrame([?string $locator]) : void

Switch to another iframe on the page.

Example:

<iframe name=\"another_frame\" id=\"fr1\" src=\"https://example.com\">\n

<?php\n# switch to iframe by name\n$I->switchToIFrame(\"another_frame\");\n# switch to iframe by CSS or XPath\n$I->switchToIFrame(\"#fr1\");\n# switch to parent page\n$I->switchToIFrame();\n
"},{"location":"modules/WPWebDriver/#switchtonexttab","title":"switchToNextTab","text":"

Signature: switchToNextTab([int $offset]) : void

Switches to next browser tab. An offset can be specified.

<?php\n// switch to next tab\n$I->switchToNextTab();\n// switch to 2nd next tab\n$I->switchToNextTab(2);\n
"},{"location":"modules/WPWebDriver/#switchtoprevioustab","title":"switchToPreviousTab","text":"

Signature: switchToPreviousTab([int $offset]) : void

Switches to previous browser tab. An offset can be specified.

<?php\n// switch to previous tab\n$I->switchToPreviousTab();\n// switch to 2nd previous tab\n$I->switchToPreviousTab(2);\n
"},{"location":"modules/WPWebDriver/#switchtowindow","title":"switchToWindow","text":"

Signature: switchToWindow([?string $name]) : void

Switch to another window identified by name.

The window can only be identified by name. If the $name parameter is blank, the parent window will be used.

Example:

<input type=\"button\" value=\"Open window\" onclick=\"window.open('https://example.com', 'another_window')\">\n

<?php\n$I->click(\"Open window\");\n# switch to another window\n$I->switchToWindow(\"another_window\");\n# switch to parent window\n$I->switchToWindow();\n

If the window has no name, match it by switching to next active tab using switchToNextTab method.

Or use native Selenium functions to get access to all opened windows:

<?php\n$I->executeInSelenium(function (\\Facebook\\WebDriver\\Remote\\RemoteWebDriver $webdriver) {\n     $handles=$webdriver->getWindowHandles();\n     $last_window = end($handles);\n     $webdriver->switchTo()->window($last_window);\n});\n
"},{"location":"modules/WPWebDriver/#type","title":"type","text":"

Signature: type(string $text, [int $delay]) : void

Type in characters on active element. With a second parameter you can specify delay between key presses.

<?php\n// activate input element\n$I->click('#input');\n\n// type text in active element\n$I->type('Hello world');\n\n// type text with a 1sec delay between chars\n$I->type('Hello World', 1);\n

This might be useful when you an input reacts to typing and you need to slow it down to emulate human behavior. For instance, this is how Credit Card fields can be filled in.

"},{"location":"modules/WPWebDriver/#typeinpopup","title":"typeInPopup","text":"

Signature: typeInPopup(string $keys) : void

Enters text into a native JavaScript prompt popup, as created by window.prompt.

"},{"location":"modules/WPWebDriver/#uncheckoption","title":"uncheckOption","text":"

Signature: uncheckOption($option) : void

"},{"location":"modules/WPWebDriver/#unselectoption","title":"unselectOption","text":"

Signature: unselectOption($select, $option) : void

Unselect an option in the given select box.

"},{"location":"modules/WPWebDriver/#wait","title":"wait","text":"

Signature: wait($timeout) : void

Wait for $timeout seconds.

"},{"location":"modules/WPWebDriver/#waitforelement","title":"waitForElement","text":"

Signature: waitForElement($element, [int $timeout]) : void

Waits up to $timeout seconds for an element to appear on the page. If the element doesn't appear, a timeout exception is thrown.

<?php\n$I->waitForElement('#agree_button', 30); // secs\n$I->click('#agree_button');\n
"},{"location":"modules/WPWebDriver/#waitforelementchange","title":"waitForElementChange","text":"

Signature: waitForElementChange($element, Closure $callback, [int $timeout]) : void

Waits up to $timeout seconds for the given element to change. Element \"change\" is determined by a callback function which is called repeatedly until the return value evaluates to true.

<?php\nuse \\Facebook\\WebDriver\\WebDriverElement\n$I->waitForElementChange('#menu', function(WebDriverElement $el) {\n    return $el->isDisplayed();\n}, 100);\n
"},{"location":"modules/WPWebDriver/#waitforelementclickable","title":"waitForElementClickable","text":"

Signature: waitForElementClickable($element, [int $timeout]) : void

Waits up to $timeout seconds for the given element to be clickable. If element doesn't become clickable, a timeout exception is thrown.

<?php\n$I->waitForElementClickable('#agree_button', 30); // secs\n$I->click('#agree_button');\n
"},{"location":"modules/WPWebDriver/#waitforelementnotvisible","title":"waitForElementNotVisible","text":"

Signature: waitForElementNotVisible($element, [int $timeout]) : void

Waits up to $timeout seconds for the given element to become invisible. If element stays visible, a timeout exception is thrown.

<?php\n$I->waitForElementNotVisible('#agree_button', 30); // secs\n
"},{"location":"modules/WPWebDriver/#waitforelementvisible","title":"waitForElementVisible","text":"

Signature: waitForElementVisible($element, [int $timeout]) : void

Waits up to $timeout seconds for the given element to be visible on the page. If element doesn't appear, a timeout exception is thrown.

<?php\n$I->waitForElementVisible('#agree_button', 30); // secs\n$I->click('#agree_button');\n
"},{"location":"modules/WPWebDriver/#waitforjs","title":"waitForJS","text":"

Signature: waitForJS(string $script, [int $timeout]) : void

Executes JavaScript and waits up to $timeout seconds for it to return true.

In this example we will wait up to 60 seconds for all jQuery AJAX requests to finish.

<?php\n$I->waitForJS(\"return $.active == 0;\", 60);\n
"},{"location":"modules/WPWebDriver/#waitforjqueryajax","title":"waitForJqueryAjax","text":"

Signature: waitForJqueryAjax([int $time]) : void

Waits for any jQuery triggered AJAX request to be resolved.

<?php\n$I->amOnPage('/triggering-ajax-requests');\n$I->waitForJqueryAjax();\n$I->see('From AJAX');\n
"},{"location":"modules/WPWebDriver/#waitfortext","title":"waitForText","text":"

Signature: waitForText(string $text, [int $timeout], [$selector]) : void

Waits up to $timeout seconds for the given string to appear on the page.

Can also be passed a selector to search in, be as specific as possible when using selectors. waitForText() will only watch the first instance of the matching selector / text provided. If the given text doesn't appear, a timeout exception is thrown.

<?php\n$I->waitForText('foo', 30); // secs\n$I->waitForText('foo', 30, '.title'); // secs\n

Read more in Codeception documentation.

"},{"location":"traits/UopzFunctions/","title":"UopzFunctions trait","text":"

This trait provides a set of methods to manipulate functions, methods and class attributes using the uopz PHP extension.

Warning

This test trait requires the uopz PHP extension.

See the Installing the extension locally section of this page for more information about how to do that. If you need to install the extension in a CI environment, see the Installing the extension in CI section of this page.

If the uopz extension is not installed, test methods using methods from the UopzFunctions trait will be marked as skipped.

"},{"location":"traits/UopzFunctions/#why-require-an-extension","title":"Why require an extension?","text":"

Why use a PHP extension instead of a user-land solution, i.e. a PHP library that does not require installing an extension?

I've written such a solution myself, function-mocker, but have grown frustrated with its limitations, and the limitation of other similar solutions.

All user-land, monkey-patching, pure PHP solutions rely on stream-wrapping. This is a very powerful feature that this project uses for some of its functionality, but it has a drawbacks when used extensively for monkey-patching functions and methods:

  • the files patch must be included after the library loaded
  • the files have to patched, or patched and cached, on each run
  • there are some random and difficult to track issues introduced by how function and method patching works; e.g. functions manipulating values by reference will not work as expected
  • some constants like __METHOD__ and __FUNCTION__ will not work as expected in the patched files
  • monkey-patching code will be \"inserted\" in the function stack, lengthening the stack trace and making it very difficult to debug
  • all this processing together with XDebug spells doom for the performance of the test suite

The uopz extension is a solid and fast solution that has been created and maintained by people that know PHP internals and the PHP language very well that has none of the drawbacks of the above-mentioned solutions.

It is just a better tool for the job.

"},{"location":"traits/UopzFunctions/#installing-the-extension-locally","title":"Installing the extension locally","text":"WindowsLinuxMacOS
  • Locate your php.ini file:
    php --ini\n
  • Download the latest DLL stable version of the extension from the releases page. You'll likely need the NTS x64 version.
  • Unzip the file and copy the php_uopz.dll file to the ext folder of your PHP installation. If your php.ini file is located at C:\\tools\\php81\\php.ini, the extensions directory will be located at C:\\tools\\php81\\ext.
  • Edit your php.ini file and add the following line to enable and configure the extension:
    extension=uopz\nuopz.exit=1\n
  • Make sure the extension is correctly installed by running php -m and making sure the uopz extension appears in the list of extensions.

You can find more information about installing PHP extensions on Windows in the PHP manual and in the uopz extension install guide.

  • Use the pecl command to install the extension:
    pecl install uopz\n
  • Configure the extension to ensure it will allow exit and die calls to terminate the script execution. Add the following line to either the main PHP configuration file (php.ini), or a dedicated configuration file:
    uopz.exit=1\n
  • Make sure the extension is correctly installed by running php -m and making sure the uopz extension appears in the list of extensions.

Alternatively, you can build the extension from source as detailed in the uopz extension install guide.

  • Use the pecl command to install the extension:
    pecl install uopz\n
  • Configure the extension to ensure it will allow exit and die calls to terminate the script execution. Add the following line to either the main PHP configuration file (php.ini), or a dedicated configuration file:
    uopz.exit=1\n
  • Make sure the extension is correctly installed by running php -m and making sure the uopz extension appears in the list of extensions.

Alternatively, you can build the extension from source as detailed in the uopz extension install guide.

"},{"location":"traits/UopzFunctions/#installing-the-extension-in-ci","title":"Installing the extension in CI","text":"

Depending on your Continuous Integration (CI) solution of choice, the configuration required to install and set up the uopz extensions will be different.

As an example, here is how you can set up the uopz extension in a GitHub Actions job:

- name: Setup PHP 8.1 with uopz\nuses: shivammathur/setup-php@v2\nwith:\n  php-version: 8.1\n  extensions: uopz\n  ini-values: uopz.exit=1\n

This project uses the very same setup.

Most CI systems are based on Linux OSes: if you're not using GitHub Actions, you can reference to the Linux local installation instructions to set up and install the extension for your CI solution of choice.

"},{"location":"traits/UopzFunctions/#usage","title":"Usage","text":"

Include the UopzFunctions trait in your test class and use the methods provided by the trait to manipulate functions, methods and class attributes.

<?php\n\nuse lucatume\\WPBrowser\\WPTestCase;\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_mock_wp_create_nonce()\n    {\n        $this->setFunctionReturn('wp_create_nonce', 'super-secret-nonce');\n\n        $this->assertEquals('super-secret-nonce', wp_create_nonce('some-action'));\n    }\n}\n

The trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

You can use the UopzFunctions trait in test cases extending the PHUnit\\Framework\\TestCase class as well:

<?php\n\nuse PHPUnit\\Framework\\TestCase;\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\n\nclass MyTest extends TestCase\n{\n    use UopzFunctions;\n\n    public function test_can_mock_my_function()\n    {\n        $this->setFunctionReturn('someFunction', 'mocked-value');\n\n        $this->assertEquals('mocked-value', someFunction());\n    }\n}\n
"},{"location":"traits/UopzFunctions/#methods","title":"Methods","text":"

The UopzFunctions trait provides the following methods:

"},{"location":"traits/UopzFunctions/#setfunctionreturn","title":"setFunctionReturn","text":"

setFunctionReturn(string $function, mixed $value, bool $execute = false): void

Set the return value for the function $function to $value.

If $value is a closure and $execute is true, then the return value will be the return value of the closure.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_function_return()\n    {\n        $this->setFunctionReturn('wp_generate_nonce', 'super-secret-nonce');\n\n        $this->assertEquals('super-secret-nonce', wp_create_nonce('some-action'));\n    }\n}\n

If $value is a closure, the original function can be called within the closure to relay the original return value:

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_function_return_with_closure()\n    {\n        $this->setFunctionReturn(\n            'wp_generate_nonce',\n            fn(string $action) => $action === 'test' ? 'test-nonce' : wp_create_nonce($action),\n            true\n        );\n\n        $this->assertEquals('test-nonce', wp_create_nonce('test'));\n        $this->assertNotEquals('test-nonce', wp_create_nonce('some-other-action'));\n    }\n}\n
"},{"location":"traits/UopzFunctions/#unsetfunctionreturn","title":"unsetFunctionReturn","text":"

unsetFunctionReturn(string $function): void

Unset the return value for the function $function previously set with setFunctionReturn.

You do not need to unset the return value for a function that was set with setFunctionReturn using unsetFunctionReturn explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#setmethodreturn","title":"setMethodReturn","text":"

setMethodReturn(string $class, string $method, mixed $value, bool $execute = false): void

Sets the return value for the static or instance method $method of the class $class to $value.

If $value is a closure and $execute is true, then the return value will be the return value of the closure.

Magic methods like __construct, __destruct, __call and so on cannot be mocked using this method. See the setClassMock method for more information about how to mock magic class methods.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass SomeLegacyClass {\n    public static function staticMethod(){\n        return 'some-static-value';\n    }\n\n    public function instanceMethod(){\n        return 'some-instance-value';\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_method_return()\n    {\n        $this->setMethodReturn(SomeLegacyClass::class, 'staticMethod', 'STATIC');\n        $this->setMethodReturn(SomeLegacyClass::class, 'instanceMethod', 'TEST');\n\n        $legacyClass = new SomeLegacyClass();\n\n        $this->assertEquals('STATIC', SomeLegacyClass::staticMethod());\n        $this->assertEquals('TEST', $legacyClass->instanceMethod());\n    }\n}\n

If $value is a closure, the original static or instance method can be called within the closure, with correctly bound self and $this context, to relay the original return value:

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass SomeLegacyClass {\n    public static function raiseStaticFlag(bool $flag = false){\n        return $flag ? 'static-flag-raised' : 'static-flag-lowered';\n    }\n\n    public function raiseFlag(bool $flag = false){\n        return $flag ? 'flag-raised' : 'flag-lowered';\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_method_return_with_closure()\n    {\n        $this->setMethodReturn(\n            SomeLegacyClass::class,\n            'raiseStaticFlag',\n            fn(bool $flag) => $flag ? 'STATIC' : self::raiseStaticFlag($flag),\n            true\n        );\n        $this->setMethodReturn(\n            SomeLegacyClass::class,\n            'raiseFlag',\n            fn(bool $flag) => $flag ? 'TEST' : $this->raiseFlag($flag),\n            true\n        );\n\n        $legacyClass = new SomeLegacyClass();\n\n        $this->assertEquals('STATIC', SomeLegacyClass::raiseStaticFlag(true));\n        $this->assertEquals('static-flag-lowered', SomeLegacyClass::raiseStaticFlag(false));\n        $this->assertEquals('TEST', $legacyClass->raiseFlag(true));\n        $this->assertEquals('flag-lowered', $legacyClass->raiseFlag(false));\n    }\n}\n
"},{"location":"traits/UopzFunctions/#unsetmethodreturn","title":"unsetmethodreturn","text":"

unsetmethodreturn(string $class, string $method): void

Unset the return value for the static or instance method $method of the class $class previously set with setMethodReturn.

You do not need to unset the return value for a method that was set with setMethodReturn using unsetMethodReturn explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#setfunctionhook","title":"setFunctionHook","text":"

setFunctionHook(string $function, Closure $hook): void

Execute $hook when entering the function $function.

Hooks can be set on both internal and user-defined functions.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_hook()\n    {\n        $log = [];\n        $this->setFunctionHook(\n            'header', \n            function($header, bool $replace = true, int $response_code = 0) use (&$log): void {\n                $log[] = $header;\n            }\n        );\n\n        header('X-Plugin-Version: 1.0.0');\n        header('X-Plugin-REST-Enabled: 1');\n        header('X-Plugin-GraphQL-Enabled: 0');\n\n        $this->assertEquals([\n            [\n                'X-Plugin-Version' => '1.0.0',\n                'X-Plugin-REST-Enabled' => '1',\n                'X-Plugin-GraphQL-Enabled' => '0'\n        ], $log);\n    }\n}\n
"},{"location":"traits/UopzFunctions/#unsetfunctionhook","title":"unsetFunctionHook","text":"

unsetFunctionHook(string $function): void

Unset the hook for the function $function previously set with setFunctionHook.

You do not need to unset the hook for a function that was set with setFunctionHook using unsetFunctionHook explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#setmethodhook","title":"setMethodHook","text":"

setMethodHook(string $class, string $method, Closure $hook): void

Execute $hook when entering the static or instance method $method of the class $class.

The keywords self and $this will be correctly bound to the class and the class instance respectively.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass LegacyApiController {\n    private static array $connections = [];\n    private ?array $cachedItems = null;\n\n    public static function connect(): self {\n        $connected = new self;\n        self::$connections[] = $connected;\n        return $connected;\n    }\n\n    public function getItems(int $count, int $from = 0): array {\n        if($this->cachedItems === null){\n            $this->cachedItems = wp_remote_get('https://example.com/items');\n        }\n\n        return array_slice($this->cachedItems, $from, $count);\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_method_hook()\n    {\n        $connections = 0;\n        $this->setMethodHook(\n            LegacyApiController::class, \n            'connect', \n            function() use (&$connections): void {\n                $connections  = count(self::$connections) + 1;\n            }\n        );\n        $itemsCacheHits = 0;\n        $this->setMethodHook(\n            LegacyApiController::class, \n            'getItems', \n            function(int $count, int $from = 0) use (&$itemsCacheHit): bool {\n                if($this->cachedItems !== null){\n                    $itemsCacheHits++;\n                }\n            }\n        );\n\n        $connectedController1 = LegacyApiController::connect();\n        $connectedController2 = LegacyApiController::connect();\n        $connectedController1->getItems(10, 0);\n        $connectedController1->getItems(10, 10);\n        $connectedController2->getItems(10, 0);\n        $connectedController2->getItems(10, 10);\n\n        $this->assertEquals(2, $connections);\n        $this->assertEquals(4, $itemsCacheHits);\n    }\n}\n
"},{"location":"traits/UopzFunctions/#unsetmethodhook","title":"unsetMethodHook","text":"

unsetMethodHook(string $class, string $method): void

Unset the hook for the static or instance method $method of the class $class previously set with setMethodHook.

You do not need to unset the hook for a method that was set with seMethodHook using unsetClassMethodHook explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#setconstant","title":"setConstant","text":"

setConstant(string $constant, mixed $value): void

Set the constant $constant to the value $value.

If the constant is not already defined, it will be defined and set to the value $value.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_constant()\n    {\n        $this->setconstant('WP_ADMIN', true);\n        $this->setconstant('TEST_CONST', 23);\n\n        $this->assertTrue(wp_is_admin());\n        $this->assertEquals(23, TEST_CONST);\n    }\n}\n
"},{"location":"traits/UopzFunctions/#unsetconstant","title":"unsetConstant","text":"

unsetConstant(string $constant): void

Unset an existing constant or restores the original value of the constant if set with setConstant.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_unset_constant()\n    {\n        // The test is starting in Admin context.\n        $this->assertTrue(is_admin());\n\n        $this->unsetConstant('WP_ADMIN');\n\n        $this->assertFalse(is_admin());\n    }\n}\n

You do not need to undefine a constant defined with setConstant using unsetConstant explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#setclassconstant","title":"setClassConstant","text":"

setClassConstant(string $class, string $constant, mixed $value): void

Set the constant $constant of the class $class to the value $value.

If the class constant is not already defined, it will be defined and set to the value $value.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyPlugin {\n    const VERSION = '89.0.0';\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_class_constant()\n    {\n        $this->setClassConstant(MyPlugin::class, 'VERSION', '23.89.0');\n        $this->setClassConstant(MyPlugin::class, 'NOT_EXISTING', 'TEST');\n\n        $this->assertEquals('23.89.0', MyPlugin::VERSION);\n        $this->assertEquals('TEST', MyPlugin::NOT_EXISTING);\n    }\n}\n
"},{"location":"traits/UopzFunctions/#unsetclassconstant","title":"unsetClassConstant","text":"

unsetClassConstant(string $class, string $constant): void

Restore the constant $constant of the class $class to its original value or removes it if it was not defined.

You do not need to undefine a constant defined with setClassConstant using undefineClassConstant explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#setclassmock","title":"setClassMock","text":"

setClassMock(string $class, string|object $mock): void

Use $mock instead of $class when creating new instances of the class $class.

This method allows you to override magic methods as well as you would do with a normal class extension.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MockPaymentApi extends PaymentApi {\n    public static function version($name, $arguments){\n        return '23.89.0';\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_class_mock()\n    {\n        $this->setClassMock(PaymentApi::class, MockPaymentApi::class);\n\n        $paymentApi = new PaymentApi();\n        $this->assertInstanceOf(MyPluginMock::class, $paymentApi);\n        $this->assertSame('23.89.0', $paymentApi::version());\n    }\n}\n

If you set the $mock to an object, then the same mock object will be used for all the new instances of the class $class:

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MockPaymentApi extends PaymentApi {\n    public function getIds($name, $arguments){\n        return [1, 23, 89];\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_class_mock()\n    {\n        $mockPaymentApi = new MockPaymentApi();\n\n        $this->setClassMock(PaymentApi::class, $mockPaymentApi);\n\n        $api1 = new PaymentApi();\n        $this->assertSame($mockPaymentApi, $api1);\n        $this->assertSame([1, 23, 89], $api1->getIds());\n        $api2 = new PaymentApi();\n        $this->assertSame($mockPaymentApi, $api2);\n        $this->assertSame([1, 23, 89], $api2->getIds());\n    }\n}\n

The $mock class, or instance, is not required to be a subclass of the class $class by the trait; although it might be required from the code you're testing by means of type hinting.

If the class or method you would like to set a mock for is final, then you can combine this method with the unsetClassFinalAttribute and unsetMethodFinalAttribute methods to avoid the final attribute being set on the class:

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nfinal class LegacyPaymentApi {\n    public function getIds(){\n        // ... fetch ids from a real external API ...\n    }\n}\n\nclass LegacyCacheController {\n    protected final function get(string $key){\n        // ... fetch data from a real cache ...\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_class_mock()\n    {\n        $this->unsetClassFinalAttribute(LegacyPaymentApi::class);\n        $mockPaymentApi = new class extends LegacyPaymentApi {\n            public function getIds(){\n                return [1, 23, 89];\n            }\n        };\n        $this->setClassMock(LegacyPaymentApi::class, $mockPaymentApi);\n        $this->unsetMethodFinalAttribute(LegacyCacheController::class, 'get');\n        $mockCacheController = new class extends LegacyCacheController {\n            public function get(string $key){\n                return 'some-value';\n            }\n        };\n\n        $paymentApi = new LegacyPaymentApi();\n\n        $this->assertSame($mockPaymentApi, $paymentApi);\n        $this->assertSame([1, 23, 89], $paymentApi->getIds());\n\n        $cacheController = new LegacyCacheController();\n\n        $this->assertSame($mockCacheController, $cacheController);\n        $this->assertSame('some-value', $cacheController->get('some-key'));\n    }\n}\n
"},{"location":"traits/UopzFunctions/#unsetclassmock","title":"unsetClassMock","text":"

unsetClassMock(string $class): void

Remove the mock for the class $class previously set with setMock.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_unset_class_mock()\n    {\n        $this->setClassMock(MyPlugin::class, new MyPluginMock());\n\n        $this->assertInstanceOf(MyPluginMock::class, new MyPlugin());\n\n        $this->unsetClassMock(MyPlugin::class);\n\n        $this->assertInstanceOf(MyPlugin::class, new MyPlugin());\n    }\n}\n

You do not need to unset the mock for a class that was set with setClassMock using unsetClassMock explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#unsetclassfinalattribute","title":"unsetClassFinalAttribute","text":"

unsetClassFinalAttribute(string $class): void

Remove the final attribute from the class $class.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nfinal class LegacyPaymentApi {}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_remove_class_final_attribute()\n    {\n        $post = static::factory()->post->createAndGet();\n\n        $this->unsetClassFinalAttribute(LegacyPaymentApi::class);\n\n        // The class is not final anymore; it can be extended for testing purposes.\n        $mockPaymentApi = new class extends LegacyPaymentApi {\n            public function getIds(){\n                return [1, 23, 89];\n            }\n        };\n\n        $this->assertSame([1, 23, 89], $mockPaymentApi->getIds());\n    }\n}\n
"},{"location":"traits/UopzFunctions/#resetclassfinalattribute","title":"resetClassFinalAttribute","text":"

resetClassFinalAttribute(string $class): void

Reset the final attribute of the class $class previously removed with the unsetClassFinalAttribute method.

You do not need to restore the class final attribute for a class that was set with unsetClassFinalAttribute using setClassFinalAttribute explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#unsetmethodfinalattribute","title":"unsetMethodFinalAttribute","text":"

unsetMethodFinalAttribute(string $class, string $method): void

Remove the final attribute from the static or instance method $method of the class $class.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_remove_method_final_attribute()\n    {\n        $this->unsetMethodFinalAttribute(LegacyAjaxController::class, 'printResponseAndExit');\n\n        // Build a class to avoid the `printResponseAndExit` method from exiting.\n        $testLegacyAdminController = new class extends LegacyAjaxController {\n            public string $response = '';\n\n            public function printResponseAndExit(){\n                $this->response = $this->template->render('list', return: true);\n                return;\n            }\n        };\n\n        // Set up things for the test ...\n\n        $testLegacyAjaxController->printResponseAndExit();\n\n        $this->assertEquals('<ul><li>Item One</li><li>Item Two</li></ul>', $testLegacyAjaxController->response);\n    }\n}\n
"},{"location":"traits/UopzFunctions/#restoremethodfinalattribute","title":"restoreMethodFinalAttribute","text":"

restoreMethodFinalAttribute(string $class, string $method): void

Restore the final attribute of the method static or instance $method of the class $class previously removed with the unsetMethodFinalAttribute method.

You do not need to restore the method final attribute for a method that was set with unsetMethodFinalAttribute using restoreMethodFinalAttribute explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#addclassmethod","title":"addClassMethod","text":"

addClassMethod(string $class, string $method, Closure $closure, bool $static = false): void

Add a public static ($static = true) or instance ($static = false) method to the class $class with the name $method and the code provided by the closure $closure.

Differently from the setClassMock method, this method will work on already existing instances of the class $class, not just new instances.

The closure $this will be bound to the class instance.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass LegacySingletonController {\n    private static $instance;\n    private array $cache = null;\n    private int $cacheCount = 0;\n\n    public static function getInstance(){\n        if(!self::$instance){\n            self::$instance = new self();\n        }\n        return self::$instance;\n    }\n\n    public function getItems(int $count, int $from = 0){\n        if($this->cache === null){\n            $this->cache = wp_remote_get('https://example.com/items');\n            $this->cacheCount = count($cache);\n        }\n\n        return array_slice($this->cache, $from, $count);\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_add_class_method()\n    {\n        $controller = LegacySingletonController::getInstance();\n\n        $this->addClassMethod(\n            LegacySingletonController::class, \n            'setCache',\n            function(array $cache): void {\n                $this->cache = $cache;\n                $this->cacheCount = count($cache);\n            }\n        );\n\n        // Set the singletong instance cache for testing purposes.\n        $controller->setCache(range(1,100));\n\n        $this->assertEquals([1,2,3], $controller->getItems(3, 0));\n    }\n
"},{"location":"traits/UopzFunctions/#removeclassmethod","title":"removeClassMethod","text":"

removeClassMethod(string $class, string $method): void

Remove the static or instance method $method added with addClassMethod from the class $class.

You do not need to remove a method added with addClassMethod, or addClassStaticMethod, using removeClassMethod explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#setobjectproperty","title":"setObjectProperty","text":"

setObjectProperty(string|object $classOrObject, string $property, mixed $value): void

If $classOrInstance is a string, set the property $property of the class $classOrObject to the value $value. If $classOrInstance is an object, set the property $property of the object $classOrObject to the value $value.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass Payment {\n    private string $uuid;\n    private string $from;\n    private string $to;\n\n    public function __construct(string $from, $string $to){\n        $this->uuid = UUID::generate();\n    }\n\n    public function getHash(): string {\n        return wp_hash(serialize([\n            'uuid' => $this->uuid\n            'from' => $this->from,\n            'to' => $this->to\n        ]));\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_object_property()\n    {\n        $payment = new Payment('Bob', 'Alice');\n\n        $this->setObjectProperty($payment, 'uuid', '550e8400-e29b-41d4-a716-446655440000');\n\n        $this->assertEquals(wp_hash(serialize([\n            'uuid' => '550e8400-e29b-41d4-a716-446655440000',\n            'from' => 'Bob',\n            'to' => 'Alice'\n        ])), $payment->getHash());\n    }\n}\n

You do not need to reset the property of an object that was set with setObjectProperty explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#getobjectproperty","title":"getObjectProperty","text":"

getObjectProperty(object $object, string $property): mixed

Get the value of the static or instance property $property of the object $object.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass LegacyController {\n    private Template $template;\n\n    public function __construct(){\n        $this->template = new Template();\n    }\n\n    // ...\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_get_object_property()\n    {\n        $controller = new LegacyController();\n\n        $templateEngine $this->getObjectProperty($controller, 'template'));\n\n        // ... do something with the template ...\n    }\n}\n
"},{"location":"traits/UopzFunctions/#resetobjectproperty","title":"resetObjectProperty","text":"

resetObjectProperty(string|object $classOrObject, string $property): void

Reset the property $property of the class $class or object $object to its original value.

You do not need to reset the property of an object that was set with setObjectProperty explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#getmethodstaticvariables","title":"getMethodStaticVariables","text":"

getMethodStaticVariables(string $class, string $method): array

Get the value of the static variables of the class $class and method $method.

The method will work for both static and instance methods of the class $class.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass RequestLogger {\n    public function log(int $code, string $response):void {\n        static $requestId;\n\n        if($requestId === null){\n            $requestId = md5(microtime());\n        }\n\n        printf(\"Request %s: %d %s\\n\", $requestId, $code, $response);\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_get_class_method_static_variables()\n    {\n        $requestLogger = new RequestLogger();\n\n        ob_start();\n        $requestLogger->log(200, 'OK');\n        $requestLogger->log(403, 'Forbidden');\n        $requestLogger->log(200, 'OK');\n        $buffer = ob_get_clean();\n\n        $requestId = $this->getClassMethodStaticVariables(RequestLogger::class, 'log')['requestId'];\n\n        $this->assertEquals(\"Request $requestId: 200 OK\\nRequest $requestId: 403 Forbidden\\nRequest $requestId: 200 OK\\n\", $buffer);\n}\n
"},{"location":"traits/UopzFunctions/#setmethodstaticvariables","title":"setMethodStaticVariables","text":"

setMethodStaticVariables(string $class, string $method, array $values): void

Set the static variablesof the class $class and method $method to the values $values.

This will work on both static and instance methods.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass ListComponent {\n    public function render(){\n        static $hash;\n\n        if(!$hash){\n            $hash = md5(microtime());\n        }\n\n        return '<ul screen=' . $hash . '><li>Item One</li><li>Item Two</li></ul>';\n    }\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_class_method_static_variables()\n    {\n        $newValues = array_merge(\n            $this->getMethodStaticVariables(ListComponent::class, 'render'),\n            ['hash' => 'some-hash']\n        );\n        $this->setClassMethodStaticVariables( ListComponent::class, 'render', [\n          'hash' => 'some-hash'\n        ]);\n\n        $component = new ListComponent();\n\n        $this->assertEquals(\n            '<ul data-screen=\"some-hash\"><li>Item One</li><li>Item Two</li></ul>', \n            $component->render()\n        );\n    }\n}\n

You do not need to reset the static variable of a class method that was set with setMethodStaticVariables explicitly using resetMethodStaticVariables explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#resetmethodstaticvariables","title":"resetMethodStaticVariables","text":"

resetMethodStaticVariables(string $class, string $method): void

Resets the static variables of the class $class method $method to their original values.

"},{"location":"traits/UopzFunctions/#setfunctionstaticvariable","title":"setFunctionStaticVariable","text":"

setFunctionStaticVariables(string $function, string $variable, mixed $value): void

Set the static variable $variable of the function $function to the value $value.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nfunction renderScreen(): string{\n    static $rendered;\n\n    if($rendered){\n        return;\n    }\n\n    $html = '<p>Some HTML</p>';\n\n    $rendered = true;\n\n    return $html;\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_function_static_variables()\n    {\n        $this->setFunctionStaticVariables('renderScreen', ['rendered' => false]);\n\n        $this->assertEquals('<p>Some HTML</p>', renderScreen());\n    }\n}\n

You do not need to reset the value of a function static variable set using the resetFunctionStaticVariables method explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#getfunctionstaticvariables","title":"getFunctionStaticVariables","text":"

getFunctionStaticVariables(string $function, ): array

Get the value of the static variable $variable of the function $function.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nfunction renderScreen(): string {\n    static $screenHash;\n\n    if(!$screenHash){\n        $screenHash = md5(microtime());\n    }\n\n    return '<p data-screen=\"' . $screenHash . '\">Some HTML</p>';\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_set_function_static_variables()\n    {\n        $screenHash = $this->getFunctionStaticVariables('renderScreen')['screenHash'];\n\n        $this->assertEquals('<p data-screen=\"' . $screenHash . '\">Some HTML</p>', renderScreen());\n    }\n}\n
"},{"location":"traits/UopzFunctions/#resetfunctionstaticvariables","title":"resetFunctionStaticVariables","text":"

resetFunctionStaticVariables(string $function): void

Resets the static variables of the function $function set with the setFunctionStaticVariables method.

"},{"location":"traits/UopzFunctions/#addfunction","title":"addFunction","text":"

addFunction(string $function, Closure $closure): void

Add a global or namespaced function to the current scope.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_add_function()\n    {\n        $this->addFunction('myGlobalFunction', fn() => 23);\n        $this->addFunction('Acme\\Project\\namespacedFunction', fn() => 89);\n\n        $this->assertEquals(23, myGlobalFunction());\n        $this->assertEquals(89, Acme\\Project\\namespacedFunction());\n    }\n}\n
"},{"location":"traits/UopzFunctions/#removefunction","title":"removeFunction","text":"

removeFunction(string $function): void

Removes the global or namespaced function $function from the current scope. This will work for functions defined using the addFunction method or defined elsewhere.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_add_function()\n    {\n        $this->addFunction('myGlobalFunction', fn() => 23);\n        $this->addFunction('Acme\\Project\\namespacedFunction', fn() => 89);\n\n        $this->removeFunction('some_plugin_function');\n        $this->removeFunction('Acme\\Project\\namespacedFunction');\n\n        // Added with addFunction.\n        $this->assertFalse(function_exists('myGlobalFunction');\n        $this->assertFalse(function_exists('Acme\\Project\\namespacedFunction');\n\n        $this->assertFalse(function_exists('some_plugin_function');\n        $this->assertFalse(function_exists('Another\\Plugin\\some_function');\n    }\n}\n

You do not need to remove a function added with addFunction using removeFunction explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"traits/UopzFunctions/#preventexit","title":"preventExit","text":"

preventExit(): void

Prevents exit or die calls executed after the method from terminating the PHP process calling exit or die.

<?php\n\nuse lucatume\\WPBrowser\\Traits\\UopzFunctions;\nuse lucatume\\WPBrowser\\TestCase\\WPTestCase;\n\nfunction printAndDie(): void{\n    print 'Some HTML';\n    die();\n}\n\nclass MyTest extends WPTestCase\n{\n    use UopzFunctions;\n\n    public function test_can_prevent_exit()\n    {\n        $this->preventExit();\n\n        ob_start();\n        printAndDie();\n        $buffer = ob_get_clean();\n\n        $this->assertEquals('Some HTML', $buffer);\n    }\n}\n
"},{"location":"traits/UopzFunctions/#restoreexit","title":"restoreExit","text":"

allowExit(): void

Restores the original behavior of the exit and die functions.

You do not need to restore the exit behavior for a exit that was prevented using preventExit using allowExit explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

"},{"location":"v3/","title":"Welcome","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

The wp-browser project provides a Codeception based solution to test WordPress plugins, themes and whole sites at all levels of testing.

The purpose of this documentation is to help you set up, run and iterate over your project and test code using the powerful APIs provided by Codeception while trying to alleviate the pains of setting it up for WordPress projects.

Throughout the documentation you will find references to test terminology: I've tried to condense those into small, digestable chunks to provide a rough idea without and a limited context; where required I tried to provide links to dive deeper into the subjects.

Happy testing!

"},{"location":"v3/codeception-4-support/","title":"Using wp-browser with Codeception 4.0","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/codeception-4-support/#using-wp-browser-with-codeception-40","title":"Using wp-browser with Codeception 4.0","text":"

Codeception version 4.0 introduced a number of new features to the framework and it's the version of wp-browser that will be maintained from now on.

I've made an effort to keep wp-browser compatible with PHP 5.6 and Codeception versions from 2.5 up.

One the biggest changes of Codeception version 4.0 is that modules have been broken out into separate packages. To use wp-browser with Codeception 4.0 all you need to do is to add this to your project composer.json file:

{\n  \"require-dev\": {\n    \"lucatume/wp-browser\": \"^2.4\",\n    \"codeception/module-asserts\": \"^1.0\",\n    \"codeception/module-phpbrowser\": \"^1.0\",\n    \"codeception/module-webdriver\": \"^1.0\",\n    \"codeception/module-db\": \"^1.0\",\n    \"codeception/module-filesystem\": \"^1.0\",\n    \"codeception/module-cli\": \"^1.0\",\n    \"codeception/util-universalframework\": \"^1.0\"\n  }\n}\n

You might not need all the modules listed here, depending on the wp-browser modules you use in your test suites. This is a scheme of what Codeception modules you will need for which wp-browser module to help you choose only the required modules:

  • \"codeception/module-asserts\" - Required for Codeception 4.0 compatibility.
  • \"codeception/module-phpbrowser\" - Required by the WPBrowser module.
  • \"codeception/module-webdriver\" - Required by the WPWebDriver module.
  • \"codeception/module-db\" - Required by the WPDb module.
  • \"codeception/module-filesystem\" - Required by the WPFilesystem module.
  • \"codeception/module-cli\" - Required by the WPCLI module.
  • \"codeception/util-universalframework\" - Required by the WordPress framework module.
"},{"location":"v3/codeception-phpunit-and-wpbrowser/","title":"Codeception, PHPUnit and wp-browser","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/codeception-phpunit-and-wpbrowser/#the-wp-browser-stack","title":"The wp-browser stack","text":"

The wp-browser project is built leveraging the power of a number of open-source projects.

While I'm not listing all of them here it's worth mentioning those that will come up, again and again, in the documentation.

"},{"location":"v3/codeception-phpunit-and-wpbrowser/#wordpress","title":"WordPress","text":"

WordPress is open source software you can use to create a beautiful website, blog, or app.

The line is taken directly from WordPress.org site.

In the context of this documentation WordPress is the PHP and JavaScript framework websites and web applications can be built on, the one anyone can download from here.

"},{"location":"v3/codeception-phpunit-and-wpbrowser/#codeception","title":"Codeception","text":"

Codeception (home) is a modern, powerful PHP testing framework written in PHP.

It comes with a number of modules and extensions that are comparable to WordPress plugins and themes.

Modules and extensions are combined in suites to be able to run a specific type of test. Each suite will handle a specific type of test for a specific set of code.

wp-browser is none other than a collection of modules and extensions for Codeception made specifically to test WordPress applications.

"},{"location":"v3/codeception-phpunit-and-wpbrowser/#phpunit","title":"PHPUnit","text":"

PHPUnit is the most widely known PHP testing framework. As the name implies it was born to make unit testing of PHP code easier but its scope and power has grown well below that.

Codeception is based, and uses, PhpUnit to wrap some of its functionalities into an easy-to-use API. The two are so compatible one with the other that Codeception can run PHPUnit tests with little to no changes.

This documentation will not cover this subject and will only deal with Codeception-native test methods but you can find more information here.

"},{"location":"v3/commands/","title":"Commands","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/commands/#custom-commands-provided-by-wp-browser","title":"Custom commands provided by wp-browser","text":"

The project comes with its own set of custom Codeception commands.

The commands provide functionalities to quickly scaffold different types of tests. Any other codecept command remains intact and available.

"},{"location":"v3/commands/#adding-the-commands-to-an-existing-project","title":"Adding the commands to an existing project","text":"

The commands are added to the main Codeception configuration file, codeception.yml, when scaffolding a project via the codecept init wp-browser command.

They can be added to any existing project adding, or editing, the commands section of the configuration file:

extensions:\n    commands:\n        - \"Codeception\\\\Command\\\\GenerateWPUnit\"\n        - \"Codeception\\\\Command\\\\GenerateWPRestApi\"\n        - \"Codeception\\\\Command\\\\GenerateWPRestController\"\n        - \"Codeception\\\\Command\\\\GenerateWPRestPostTypeController\"\n        - \"Codeception\\\\Command\\\\GenerateWPAjax\"\n        - \"Codeception\\\\Command\\\\GenerateWPCanonical\"\n        - \"Codeception\\\\Command\\\\GenerateWPXMLRPC\"\n
"},{"location":"v3/commands/#generation-commands","title":"Generation commands","text":"

The library provides commands to quickly scaffold integration test cases for specific types of WordPress components, see levels of testing for more information.

The tests are almost identical to the ones you could write in a PHPUnit based Core suite with the exception of extending the Codeception\\TestCase\\WPTestCase test case.

"},{"location":"v3/commands/#generatewpunit","title":"generate:wpunit","text":"

Generates a test case extending the \\Codeception\\TestCase\\WPTestCase class using the

  codecept generate:wpunit suite SomeClass\n

The command will generate a skeleton test case like

<?php\n\nclass SomeClassTest extends \\Codeception\\TestCase\\WPTestCase\n{\n    public function setUp()\n    {\n      parent::setUp();\n    }\n\n    public function tearDown()\n    {\n      parent::tearDown();\n    }\n\n    // tests\n    public function testMe()\n    {\n    }\n\n}\n
"},{"location":"v3/commands/#generatewprest","title":"generate:wprest","text":"

Generates a test case extending the \\Codeception\\TestCase\\WPRestApiTestCase class using the

  codecept generate:wprest suite SomeClass\n

The command will generate a skeleton test case like

<?php\n\nclass SomeClassTest extends \\Codeception\\TestCase\\WPRestApiTestCase\n{\n    public function setUp()\n    {\n      parent::setUp();\n    }\n\n    public function tearDown()\n    {\n      parent::tearDown();\n    }\n\n    // tests\n    public function testMe()\n    {\n    }\n\n}\n
"},{"location":"v3/commands/#generatewprestcontroller","title":"generate:wprestcontroller","text":"

Generates a test case extending the \\Codeception\\TestCase\\WPRestControllerTestCase class using the

  codecept generate:wprest suite SomeClass\n

The command will generate a skeleton test case like

<?php\n\nclass SomeClassTest extends \\Codeception\\TestCase\\WPRestControllerTestCase\n{\n    public function setUp()\n    {\n      parent::setUp();\n    }\n\n    public function tearDown()\n    {\n      parent::tearDown();\n    }\n\n    // tests\n    public function testMe()\n    {\n    }\n\n}\n
"},{"location":"v3/commands/#generatewprestposttypecontroller","title":"generate:wprestposttypecontroller","text":"

Generates a test case extending the \\Codeception\\TestCase\\WPRestPostTypeControllerTestCase class using the

  codecept generate:wprest suite SomeClass\n

The command will generate a skeleton test case like

<?php\n\nclass SomeClassTest extends \\Codeception\\TestCase\\WPRestPostTypeControllerTestCase\n{\n    public function setUp()\n    {\n      parent::setUp();\n    }\n\n    public function tearDown()\n    {\n      parent::tearDown();\n    }\n\n    // tests\n    public function testMe()\n    {\n    }\n\n}\n
"},{"location":"v3/commands/#generatewpajax","title":"generate:wpajax","text":"

Generates a test case extending the \\Codeception\\TestCase\\WPAjaxTestCase class using the

  codecept generate:wpajax suite SomeClass\n

The command will generate a skeleton test case like

<?php\n\nclass SomeClassTest extends \\Codeception\\TestCase\\WPAjaxTestCase\n{\n    public function setUp()\n    {\n      parent::setUp();\n    }\n\n    public function tearDown()\n    {\n      parent::tearDown();\n    }\n\n    // tests\n    public function testMe()\n    {\n    }\n\n}\n
"},{"location":"v3/commands/#generatewpxmlrpc","title":"generate:wpxmlrpc","text":"

Generates a test case extending the \\Codeception\\TestCase\\WPXMLRPCTestCase class using the

  codecept generate:wpxmlrpc suite SomeClass\n

The command will generate a skeleton test case like

<?php\n\nclass SomeClassTest extends \\Codeception\\TestCase\\WPXMLRPCTestCase\n{\n    public function setUp()\n    {\n      parent::setUp();\n    }\n\n    public function tearDown()\n    {\n      parent::tearDown();\n    }\n\n    // tests\n    public function testMe()\n    {\n    }\n\n}\n
"},{"location":"v3/commands/#generatewpcanonical","title":"generate:wpcanonical","text":"

Generates a test case extending the \\Codeception\\TestCase\\WPCanonicalTestCase class using the

  codecept generate:wpcanonical suite SomeClass\n

The command will generate a skeleton test case like

<?php\n\nclass SomeClassTest extends \\Codeception\\TestCase\\WPCanonicalTestCase\n{\n    public function setUp()\n    {\n      parent::setUp();\n    }\n\n    public function tearDown()\n    {\n      parent::tearDown();\n    }\n\n    // tests\n    public function testMe()\n    {\n    }\n\n}\n
"},{"location":"v3/configuration/","title":"Configuration","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/configuration/#initializing-wp-browser","title":"Initializing wp-browser","text":"

While wp-browser can be configured manually creating each file the fastest way to bootstrap its configuration is by using its initialization template.

Throughout the steps below I will use the WordPress setup I've prepared before From the root folder of the project, /Users/luca/Sites/wordpress/wp-content/plugins/acme-plugin in the example, run the command:

vendor/bin/codecept init wpbrowser\n

Composer installed Codeception binary (codecept) in the vendor folder of my project.

With the command above I'm telling Codeception to initialize a wp-browser project in the current folder. When I click enter I'm presented with a list of questions, each answer will be used to configure the wp-browser project for me; one by one.

In the screenshot the answers I've provided to each question, with reference to the setup above:

wp-browser will try to provide a brief explanation of what each question is but below is the long version.

"},{"location":"v3/configuration/#long-question-explanation","title":"Long question explanation","text":"

I've tried to condense as much clarity as possible in the questions the codecept init wpbrowser command will ask but, for sake of brevity and space, there's no way I could provide inline a deeper explanation of each.

Below is a longer explanation of each question:

  • How would you like the acceptance suite to be called?
  • How would you like the functional suite to be called?
  • How would you like the WordPress unit and integration suite to be called?
  • How would you like to call the env configuration file?
  • Where is WordPress installed?
  • What is the path, relative to WordPress root URL, of the admin area of the test site?
  • What is the name of the test database used by the test site?
  • What is the host of the test database used by the test site?
  • What is the user of the test database WPLoader should use?
  • What is the password of the test database WPLoader should use?
  • What is the table prefix of the test database WPLoader should use?
  • What is the URL the test site?
  • What is the email of the test site WordPress administrator?
  • What is the title of the test site?
  • What is the login of the administrator user of the test site?
  • What is the password of the administrator user of the test site?
  • Are you testing a plugin, a theme or a combination of both?
  • What is the folder/plugin.php name of the plugin?
  • Are you developing a child theme?
  • Are you using a child theme?
  • What is the slug of the parent theme?
  • What is the slug of the theme?
  • What is the slug of the theme you are using?
  • Does your project needs additional plugins to be activated to work?
"},{"location":"v3/configuration/#how-would-you-like-the-acceptance-suite-to-be-called","title":"How would you like the acceptance suite to be called?","text":"

With reference to the testing levels definition this question provides you with the possibility to change the name of the acceptance-like test suite.

Common, alternative, names are ui, rest and user.

"},{"location":"v3/configuration/#how-would-you-like-the-functional-suite-to-be-called","title":"How would you like the functional suite to be called?","text":"

With reference to the testing levels definition this question provides you with the possibility to change the name of the functional-like test suite.

A common alternative name is service.

"},{"location":"v3/configuration/#how-would-you-like-the-wordpress-unit-and-integration-suite-to-be-called","title":"How would you like the WordPress unit and integration suite to be called?","text":"

With reference to the testing levels definition this question provides you with the possibility to change the name of the suite dedicated to integration and \"WordPress unit\" tests.

A common alternative name is integration.

"},{"location":"v3/configuration/#how-would-you-like-to-call-the-env-configuration-file","title":"How would you like to call the env configuration file?","text":"

Instead of configuring each module in each suite with the same parameters over and over Codeception supports dynamic configuration via environment files.

wp-browser will scaffold such a configuration for you and will use, by default, a file called .env to store the configuration parameters.

The file name might not suit all setups especially and this question allows changing that file name; common, alternative, file names are .env.tests, .env.codeception and similar.

"},{"location":"v3/configuration/#where-is-wordpress-installed","title":"Where is WordPress installed?","text":"

During tests the test code will need to access WordPress code, precisely wp-browser requires being pointed to the folder that contains the wp-load.php file.

The answer can be an absolute path, like /Users/luca/Sites/wordrpress, or a path relative to the folder where Codeception is installed like vendor/wordpress.

This path should be accessible by the machine that is running the tests; if you're running the tests from your machine (e.g. your laptop) that's just the path to the folder where WordPress is installed, /Users/luca/Sites/wordpress in the example configuration above.

If you are, instead, running the tests from within a virtualized machine (e.g. Vagrant or Docker) then the path should be the one used by the virtualized machine.

To make an example:

  • on my machine WordPress is installed at /Users/luca/Sites/wordpress
  • I've created a Docker container using the official WordPress image and bound the above folder into the container
  • internally the container will put WordPress in the /var/www/html folder

If I run the tests from my host machine then WordPress root directory will be /Users/luca/Sites/wordpress, if I run the tests from within the Docker container then WordPress root folder will be /var/www/html.

Another example is Local by Flywheel:

  • in the host machine the path to the WordPress root folder will be /Users/luca/Local\\ Sites/wordpress/app/public
  • from within the Docker container managed by Local the path will be /app/public

If you need a solution that will work in both instances use a relative path: wp-browser will accept paths like ./../../../wordpress and will attempt to resolve them.

"},{"location":"v3/configuration/#what-is-the-path-relative-to-wordpress-root-url-of-the-admin-area-of-the-test-site","title":"What is the path, relative to WordPress root URL, of the admin area of the test site?","text":"

This is usually /wp-admin but you might have the web-server, or a plugin, redirect or hide requests for the administration area to another path.

Some examples are /admin, /login and the like.

Mind that this is not the path to the login page but the path to the administrationo area; this will be used by wp-browser to find to the administration area in acceptance and functional tests.

"},{"location":"v3/configuration/#what-is-the-name-of-the-test-database-used-by-the-test-site","title":"What is the name of the test database used by the test site?","text":"

In my example setup it's wordpress.

This is the name of the database that is storing the information used by the site I can reach at http://localhost:8080.

I want to underline the word \"test\". Any site and any database you use and expose to wp-browser should be intended for tests; this means that it does not contain any data you care about as it will be lost.

"},{"location":"v3/configuration/#what-is-the-host-of-the-test-database-used-by-the-test-site","title":"What is the host of the test database used by the test site?","text":"

In my example setup it's 127.0.0.1:3306.

Here the same principle valid for Where is WordPress installed? applies: the database host is relative to the machine that is running the tests.

In my example I'm hosting the database locally, on my laptop, and my machine can reach it at the localhost address (127.0.0.1) on MySQL default port (3306).

If I am using the database of a Local by Flywheel site from my host machine then it might be something like 192.168.92.100:4050 (from the site \"Database\" tab); the same principle applies if I am using a Vagrant-based or Docker-based solution.

If I am running the tests from within a virtualized machine (a Docker container, a Vagrant box et cetera) then it would probably be localhost or 1270.0.0.1.

This detail will be used in the context of acceptance and functional tests by the WPDb module.

"},{"location":"v3/configuration/#what-is-the-user-of-the-test-database-used-by-the-test-site","title":"What is the user of the test database used by the test site?","text":"

In my example setup it's root as I'm using MySQL server root user to access the database during tests.

Depending on your setup it might be different; since wp-browser will need to not only read but write too to the database make sure to use a user that has full access to the database specified in the answer to the What is the host of the test database used by the test site? question.

This detail will be used in the context of acceptance and functional tests by the WPDb module.

"},{"location":"v3/configuration/#what-is-the-password-of-the-test-database-used-by-the-test-site","title":"What is the password of the test database used by the test site?","text":"

In my example setup it's empty as I've not set any password for the root account.

In your case it might be different and it should be the password associated with the user specified in the answer to the What is the user of the test database used by the test site? question.

This detail will be used in the context of acceptance and functional tests by the WPDb module.

"},{"location":"v3/configuration/#what-is-the-table-prefix-of-the-test-database-used-by-the-test-site","title":"What is the table prefix of the test database used by the test site?","text":"

In my example setup it's wp_; that value is taken from the WordPress installation configuration file.

To have any influence on the site wp-browser will need to modify the same database tables WordPress is using; as I did you can take this value from the wp-config.php file directly: it's the value of the $table_prefix variable.

This detail will be used in the context of acceptance and functional tests by the WPDb module.

"},{"location":"v3/configuration/#what-is-the-name-of-the-test-database-wploader-should-use","title":"What is the name of the test database WPLoader should use?","text":"

In my example setup it's tests.

During integration, or WordPress \"unit\" tests, wp-loader will need to load WordPress code.

Since WordPress code is not meant to be \"modular\" it does not support auto-loading or loading just parts of it; it's either almost all or nothing.

One of the first things WordPress does, when loading, is trying to connect to a database: if that database is not available then WordPress will not load.

In the answer to the question Where is WordPress installed? I've told wp-browser where to find WordPress code, in this answer I'm telling wp-browser what database it should use to bootstrap WordPress.

This detail will be used by the WPLoader module to bootstrap WordPress. It's highly recommended to use a different database from the one used for functional and acceptance tests.

"},{"location":"v3/configuration/#what-is-the-host-of-the-test-database-wploader-should-use","title":"What is the host of the test database WPLoader should use?","text":"

In my example setup it's 127.0.0.1:3306.

As in the answer to the question What is the name of the test database WPLoader should use? we're providing connection details about the database that should be used to bootstrap WordPress during integration and WordPress \"unit\" tests.

Again the database host is in relation to the machine running the tests, all the considerations done for What is the host of the test database used by the test site? apply.

This detail will be used by the WPLoader module to bootstrap WordPress.

"},{"location":"v3/configuration/#what-is-the-user-of-the-test-database-wploader-should-use","title":"What is the user of the test database WPLoader should use?","text":"

In my example it's root.

Similar to the question What is the user of the test database used by the test site? but in relation to the database specified in the question What is the name of the test database WPLoader should use?.

This detail will be used by the WPLoader module to bootstrap WordPress.

"},{"location":"v3/configuration/#what-is-the-password-of-the-test-database-wploader-should-use","title":"What is the password of the test database WPLoader should use?","text":"

In my example setup it's empty as I've not set any password for the root account.

Similar to the question What is the password of the test database used by the test site? but in relation to the database specified in the question What is the name of the test database WPLoader should use?.

This detail will be used by the WPLoader module to bootstrap WordPress.

"},{"location":"v3/configuration/#what-is-the-table-prefix-of-the-test-database-wploader-should-use","title":"What is the table prefix of the test database WPLoader should use?","text":"

In my example setup it's wp_.

Similar to the question What is the table prefix of the test database used by the test site? but in relation to the database specified in the question What is the name of the test database WPLoader should use?.

This detail will be used by the WPLoader module to bootstrap WordPress.

"},{"location":"v3/configuration/#what-is-the-url-the-test-site","title":"What is the URL the test site?","text":"

In my example setup it's http://localhost:8080.

This is the full URL you would have to enter in the browser, on the machine that is running the tests, to reach the test WordPress site homepage.

"},{"location":"v3/configuration/#what-is-the-email-of-the-test-site-wordpress-administrator","title":"What is the email of the test site WordPress administrator?","text":"

In my example setup it's admin@wp.localhost.

This detail will be used by the WPLoader module to bootstrap WordPress and, while required, it's usually not relevant unless you're testing email communications.

"},{"location":"v3/configuration/#what-is-the-title-of-the-test-site","title":"What is the title of the test site?","text":"

In my example setup it's Acme Plugin Test Site.

This detail will be used by the WPLoader module to bootstrap WordPress and, while required, it's usually not relevant unless you're testing around the site title.

"},{"location":"v3/configuration/#what-is-the-login-of-the-administrator-user-of-the-test-site","title":"What is the login of the administrator user of the test site?","text":"

In my example setup it's admin.

This detail will be used by the WPBrowser or WPWebDriver modules to fill in the login details for the administrator user.

It should be the same as the one that allows you to access the site administration area in the WordPress test site, http://localhost:8080/wp-admin in my example.

"},{"location":"v3/configuration/#what-is-the-password-of-the-administrator-user-of-the-test-site","title":"What is the password of the administrator user of the test site?","text":"

In my example setup it's password.

This detail will be used by the WPBrowser or WPWebDriver modules to fill in the login details for the administrator user.

It should be the same as the one that allows you to access the site administration area in the WordPress test site, http://localhost:8080/wp-admin in my example.

"},{"location":"v3/configuration/#are-you-testing-a-plugin-a-theme-or-a-combination-of-both","title":"Are you testing a plugin, a theme or a combination of both?","text":"

Depending on the answer the WPLoader module will load, during integration or WordPress \"unit\" tests, your WordPress plugin or theme.

If you replied with both (for \"a combination of both\") then you'll be able to choose the plugins and theme to load in integration and WordPress \"unit\" tests in the following questions.

"},{"location":"v3/configuration/#what-is-the-folderpluginphp-name-of-the-plugin","title":"What is the folder/plugin.php name of the plugin?","text":"

This question will be asked only if you replied plugin to the question Are you testing a plugin, a theme or a combination of both?. In my example setup it's acme-plugin/plugin.php.

This is the <folder>/<main-plugin-file>.php path, relative to the WordPress installation plugins folder, to the plugin you are testing.

The main plugin file is the one that contains the plugin header.

This detail will be used by the WPLoader module to bootstrap WordPress and load your plugin or theme in integration and WordPress \"unit\" tests.

"},{"location":"v3/configuration/#are-you-developing-a-child-theme","title":"Are you developing a child theme?","text":"

This question will be asked only if you replied theme to the question Are you testing a plugin, a theme or a combination of both?. Enter yes if you are developing a child theme.

This detail will be used by the WPLoader module to bootstrap WordPress and load a parent theme along with your theme in integration and WordPress \"unit\" tests.

Please note that wp-browser will not download and install the parent theme in the WordPress installation for you.

"},{"location":"v3/configuration/#are-you-using-a-child-theme","title":"Are you using a child theme?","text":"

This question will be asked only if you replied both to the question Are you testing a plugin, a theme or a combination of both?. Enter yes if you are using a child theme.

This detail will be used by the WPLoader module to bootstrap WordPress and load a parent theme along with your theme in integration and WordPress \"unit\" tests.

Please note that wp-browser will not download and install the parent theme in the WordPress installation for you.

"},{"location":"v3/configuration/#what-is-the-slug-of-the-parent-theme","title":"What is the slug of the parent theme?","text":"

This question will be asked only if you replied yes to the question Are you developing a child theme?.

Reply with the slug of the parent theme, that's usually the name of the folder the parent theme lives in, e.g. twentyseventeen.

This detail will be used by the WPLoader module to bootstrap WordPress and load a parent theme along with your theme in integration and WordPress \"unit\" tests.

Please note that wp-browser will not download and install the parent theme in the WordPress installation for you.

"},{"location":"v3/configuration/#what-is-the-slug-of-the-theme","title":"What is the slug of the theme?","text":"

This question will be asked only if you replied theme to the question Are you testing a plugin, a theme or a combination of both?. Reply with the slug of the theme, that's usually the name of the folder the theme lives in, e.g. twentyseventeen.

This detail will be used by the WPLoader module to bootstrap WordPress and load your theme in integration and WordPress \"unit\" tests.

"},{"location":"v3/configuration/#what-is-the-slug-of-the-theme-you-are-using","title":"What is the slug of the theme you are using?","text":"

This question will be asked only if you replied both to the question Are you testing a plugin, a theme or a combination of both?. Reply with the slug of the theme you are using, that's usually the name of the folder the theme lives in, e.g. twentyseventeen.

This detail will be used by the WPLoader module to bootstrap WordPress and load the theme integration and WordPress \"unit\" tests.

"},{"location":"v3/configuration/#does-your-project-needs-additional-plugins-to-be-activated-to-work","title":"Does your project needs additional plugins to be activated to work?","text":"

Whether you're testing a plugin, a theme or a combination of both you might need some additional plugins to run your tests.

As an example if I'm testing a WooCommerce extension I need the WooCommerce plugin to test it; this is the place where I can define it.

The required plugins follow the same format as the one used in the question What is the folder/plugin.php name of the plugin?: <plugin-folder>/<plugin-main-file>.php; in the case of WooCommerce it would be woocommerce/woocommerce.php.

This detail will be used by the WPLoader module to bootstrap WordPress and load the required plugins in integration and WordPress \"unit\" tests.

Please note that wp-browser will not download and install the required plugins in the WordPress installation for you.

"},{"location":"v3/configuration/#if-you-entered-a-wrong-value","title":"If you entered a wrong value","text":"

No worries, just correct the value in the environment file or in the suites configuration files.

The environment file will have the name you specified in the answer the question How would you like to call the env configuration file?.

The suites configuration files can be found in tests/<suite>.suite.yml; e.g. the wpunit suite configuration file will be tests/wpunit.suite.yml file.

"},{"location":"v3/configuration/#final-steps","title":"Final steps","text":"

To complete the setup I have removed any demo content from the site and activated my plugin in the plugins administration page.

In the tests/acceptance.suite.yml file and in the tests/functional.suite.yml file, the configuration file for the acceptance and functional suites respectively, the WPDb module configuration contains a dump configuration parameter:

class_name: AcceptanceTester\nmodules:\n    enabled:\n        - WPDb\n    config:\n        WPDb:\n            dump: 'tests/_data/dump.sql'\n

The dump parameter is inherited by the WPDb module from the Codeception Db module and defines the SQL dump file that should be loaded before, and between, tests to reset the testing environment to a base known state.

As for any other database-related operation wp-browser will not create the dump for me. I use MySQL binary to export the database state (a dump) with the command:

mysqldump -u root -h 127.0.0.1 -P 3306 wordpress > /Users/luca/Sites/wordpress/wp-content/plugins/acme-plugin/tests/_data/dump.sql\n

I could use any other combination of tools to produce the dump; using mysql binary is not a requirement.

Graphic interfaces like SequelPro, Adminer and the like would be perfectly fine.

"},{"location":"v3/configuration/#pre-flight-check","title":"Pre-flight check","text":"

There is one last check I need to make before jumping into the creation of tests: making sure all the paths and credentials I've configured wp-browser with are correct.

The bootstrap process generated four suites for me: acceptance, functional, integration and unit. If you have modified the default suite names during the setup your suites names might differ though.

To test the setup I will run each suite and make sure it can run correctly empty of any test. To run a suite of tests I will use the codecept run command:

codecept run acceptance\ncodecept run functional\ncodecept run integration\ncodecept run unit\n

How comes I'm not using the command codecept run (without specifying the suite names)? See the FAQ entry.

If you cannot run all the suites without issues then check your configuration settings again, read the errors and see If you entered a wrong value

"},{"location":"v3/events-api/","title":"Events API","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/events-api/#events-api","title":"Events API","text":"

Codeception comes with a set of events modules and extensions can subscribe to.

Codeception Events API is, but, only available to Modules and Extensions, and while that might be good for most cases, it might not cover a number of edge cases.

Similarly to WordPress add_action function, wp-browser provides the tad\\WPBrowser\\addListener function:

function addListener($eventName, callable $listener, $priority = 0);\n

The priority works the reverse way as it does in WordPress: highest number will be processed first!

Again similarly to WordPress do_action function, the tad\\WPBrowser\\dispatch function:

function dispatch($eventName, $origin = null, array $context = []);\n

This is the kind of API that is better shown with an example, though.

"},{"location":"v3/events-api/#example","title":"Example","text":"

In this example I'm writing acceptance tests and would like to avoid the performance hit that the cleanup configuration parameter of the Db, or WPDb, module implies. The cleanup parameter will trigger the drop of all tables in the test database and the re-import of the SQL dump file, or files, between each test. This will ensure a clean starting fixture between tests, but for larger setup fixtures this might be a long operation that wastes precious seconds when, say, the only change is the addition of 3 posts, as in this example.

The Events API allows implementing a tailored clean-up procedure that can avoid costly clean ups between tests.

In the suite bootstrap file, e.g. tests/acceptance/_bootstrap.php, I add a listener on the my-plugin-test/setup-posts event. The event will contain information about what post IDs I've set up in the tests and will provide an instance of the tester object to handle database manipulation. With that information, the costly cleanup procedure can be avoided.

<?php\n\n$registerPostsCleanup = static function (tad\\WPBrowser\\Events\\WpbrowserEvent $event) {\n    $ids = $event->get('ids', []);\n    /** @var \\EventsTester $db */\n    $db = $event->get('db');\n\n    // When tests are done, then remove all the posts we've created at the start of the test, if any.\n    tad\\WPBrowser\\addListener(\n        Codeception\\Events::TEST_AFTER,\n        static function () use ($ids, $db) {\n            foreach ($ids as $id) {\n                $db->dontHavePostInDatabase([ 'ID' => $id ], true);\n                // Ensure the clean up did happen correctly.\n                $db->dontSeePostInDatabase([ 'ID' => $id ]);\n                $db->dontSeePostMetaInDatabase([ 'post_id' => $id ]);\n            }\n        }\n    );\n};\n\n// Listen for this event to register the posts to remove, along with their custom fields, after the test.\ntad\\WPBrowser\\addListener('test-event-1/setup-posts', $registerPostsCleanup);\n

In this simple test I'm adding 3 posts [using the factory provided by the WPLoader module in loadOnly mode][2] and want to make sure those, and the relative meta, are removed at the end of the tests. The WPDb module, extending the Db module from Codeception, will remove the inserted rows, but will not take care of modified rows, or rows not inserted by the WPDb module.

Mirroring the requirement of the clean up function I've defined above, I'm passing the post IDs of the posts I've created and the current tester to provide the clean up function with database handling capabilities.

<?php\n/** @var Codeception\\Scenario $scenario */\n$I = new AcceptanceTester($scenario);\n$I->wantTo('add posts and clean them up using the Events API');\n\n/*\n * Use WordPress methods, thanks to the `WPLoader` module, to use WordPress, or our own, API to insert posts.\n * This will prevent, but, `WPDb` from removing the inserted rows and clean up, so we remove the posts and meta\n * with an event and our custom clean-up function.\n */\n$ids = $I->factory()->post->create_many(3, [ 'post_type' => 'some_post_type' ]);\n\ntad\\WPBrowser\\dispatch('test-event-1/setup-posts', __FILE__, [\n    'ids' => $ids,\n    'db'  => $I\n]);\n
"},{"location":"v3/extensions/","title":"Extensions","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/extensions/#extensions","title":"Extensions","text":"

The Codeception testing framework can be extended in a number of ways.

The one this project leverages the most are modules but [extensions are another way].

Modules extend the functionality of Codeception in the context of the tests, while extensions extend its interaction capacities; this is by no means a strict rule but that's usually the case.

The package contains two additional extensions to facilitate testers' life.

"},{"location":"v3/extensions/#symlinker","title":"Symlinker","text":"

The tad\\WPBrowser\\Extension\\Symlinker extension provides an automation to have the Codeception root directory symbolically linked in a WordPress local installation.

Since version 3.9 WordPress supports this feature (with some precautions) and the extension takes charge of:

  • symbolically linking a plugin or theme folder in the specified destination before any suite boots up
  • unlinking that symbolic link after all of the suites did run

It's the equivalent of doing something like this from the command line (on a Mac):

ln -s /my/central/plugin/folder/my-plugin /my/local/wordpress/installation/wp-content/plugins/my-plugin\n/my/central/plugin/folder/my-plugin/vendor/bin/codecept run\nrm -rf /my/local/wordpress/installation/wp-content/plugins/my-plugin\n

The extension needs small configuration in the codeception.yml file:

extensions:\n    enabled:\n        - tad\\WPBrowser\\Extension\\Symlinker\n    config:\n        tad\\WPBrowser\\Extension\\Symlinker:\n            mode: plugin\n            destination: /my/local/wordpress/installation/wp-content/plugins\n            rootFolder: /some/plugin/folder\n

The arguments are:

  • mode - can be plugin or theme and indicates whether the current Codeception root folder being symlinked is a plugin or a theme one
  • destination - the absolute path to the WordPress local installation plugins or themes folder; to take the never ending variety of possible setups into account the extension will make no checks on the nature of the destination: could be any folder.
  • rootFolder - optional absolute path to the WordPress plugin or theme to be symlinked root folder; will default to the Codeception root folder
"},{"location":"v3/extensions/#copier","title":"Copier","text":"

The tad\\WPBrowser\\Extension\\Copier extension provides an automation to have specific files and folders copied to specified destination files and folders before the suites run.

While WordPress handles symbolic linking pretty well there are some cases, like themes and drop-ins, where there is a need for \"real\" files to be put in place.

One of such cases is, currently, one where Docker is used to to host and serve the code under test: symbolically linked files cannot be bound inside a container and Docker containers will fail to start in this case.

The extension follows the standard Codeception extension activation and has one configuration parameter only:

extensions:\n    enabled:\n        - tad\\WPBrowser\\Extension\\Copier\n    config:\n        tad\\WPBrowser\\Extension\\Copier:\n            files:\n                tests/_data/required-drop-in.php: /var/www/wordpress/wp-content/drop-in.php\n                tests/_data/themes/dummy: /var/www/wordpress/wp-content/themes/dummy\n                /Users/Me/Repos/required-plugin: /var/www/wordpress/wp-content/plugins/required-plugin.php\n                /Users/Me/Repos/mu-plugin.php: ../../../../wp-content/mu-plugins/mu-plugin.php\n

The extension will handle absolute and relative paths for sources and destinations and will resolve relative paths from the project root folder.

When copying directories the extension will only create the destination folder and not the folder tree required; in the example configuration above the last entry specifies that a mu-plugin.php file should be copied to the mu-plugins folder: that mu-plugins folder must be there already.

"},{"location":"v3/extensions/#environments-support","title":"Environments support","text":"

Being able to symlink a plugin or theme folder into a WordPress installation for testing purposes could make sense when trying to test, as an example, a plugin in a single site and in multi site environment.

Codeception supports environments and the extension does as well specifying a destination for each.

As an example the acceptance.suite.yml file might be configured to support single and multisite environments:

env:\n    single:\n        modules:\n            config:\n                WPBrowser:\n                    url: 'http://wp.dev'\n                WPDb:\n                    dsn: 'mysql:host=127.0.0.1;dbname=wp'\n    multisite:\n        modules:\n            config:\n                WPBrowser:\n                    url: 'http://mu.dev'\n                WPDb:\n                    dsn: 'mysql:host=127.0.0.1;dbname=mu'\n

In the codeception.yml file specifying a destination for each supported environment will tell the extension to symbolically link the plugin or theme file to different locations according to the current environment:

extensions:\n    enabled:\n        - tad\\WPBrowser\\Extension\\Symlinker\n    config:\n        tad\\WPBrowser\\Extension\\Symlinker:\n            mode: plugin\n            destination:\n                single: /var/www/wp/wp-content/plugins\n                multisite: /var/www/mu/wp-content/plugins\n

If no destination is specified for the current environment the extension will fallback to the first specified one.

A default destination can be specified to override this behaviour.

extensions:\n    enabled:\n        - tad\\WPBrowser\\Extension\\Symlinker\n    config:\n        tad\\WPBrowser\\Extension\\Symlinker:\n            mode: plugin\n            destination:\n                default: /var/www/default/wp-content/plugins\n                single: /var/www/wp/wp-content/plugins\n                multisite: /var/www/mu/wp-content/plugins\n

When running a suite specifying more than one environment like

codecept run acceptance --env foo,baz,multisite\n

Then the extension will use the first matched one, in the case above the multisite destination will be used.

The rootFolder parameter too can be set to be environment-aware and it will follow the same logic as the destination:

extensions:\n    enabled:\n        - tad\\WPBrowser\\Extension\\Symlinker\n    config:\n        tad\\WPBrowser\\Extension\\Symlinker:\n            mode: plugin\n            rootFolder:\n                dev: /\n                dist: /dist\n                default: /\n            destination:\n                default: /var/www/dev/wp-content/plugins\n                dev: /var/www/dev/wp-content/plugins\n                dist: /var/www/dist/wp-content/plugins\n

When running a suite specifying more than one environment like

codecept run acceptance --env dist\n

Then the extension will symlink the files from /dist into the /var/www/dist/wp-content/plugins folder.

"},{"location":"v3/extensions/#events","title":"Events","text":"

Due to some internal changes in Codeception 4.0, the internal API (really a collection of low-level hacks on my part) that allowed wp-browser to dispatch, and listen for, events in the modules has been removed.

If you want to leverage [the event system wp-browser provides] with Codeception default events (e.g. suite.init or test.before), then you will need to use this extension.

You will not need this extension if you're not using Codeception version 4.0.

You will need to enable it in your Codeception main configuration file (e.g. codeception.dist.yml).

extensions:\n    enabled:\n        - tad\\WPBrowser\\Extension\\Events\n    config:\n      tad\\WPBrowser\\Extension\\Events:\n        suites: ['acceptance']\n

The extension only configuration is the suites parameter that allows specifying the suites the extension should apply to. If the suites parameter is not specified, then the extension will apply to all suites.

"},{"location":"v3/faq/","title":"Frequently asked questions","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/faq/#some-common-questions","title":"Some common questions","text":"

There are questions I keep receiving via email, GitHub or in person at conferences.

I tried to address some of them here.

"},{"location":"v3/faq/#is-codeceptionwp-browser-php-52-compatible","title":"Is Codeception/wp-browser PHP 5.2 compatible?","text":"

No, Codeception, and wp-browser by extension, will require PHP 5.6 minimum.

This does not mean your code cannot be PHP 5.2 compatible: you can test your code using all the possibilities of newer PHP versions and still keep it PHP 5.2 compatible.

Just because you can doesn't mean you should though: this documentation will assume a minimum PHP version, for the example and test code, of PHP 5.6.

"},{"location":"v3/faq/#can-i-run-unit-tests-with-wp-browsercodeception","title":"Can I run unit tests with wp-browser/Codeception?","text":"

Yes, with some distinctions.

In the WordPress ecosystem there's a tendency to call any kind of test a \"unit test\". Under that definition will fall tests that are not \"unit\" tests at all.

Without drowning into a long and painful battle for definitions this guide will use the following definitions for different levels of testing.

The next section will detail the conventions this documentation uses to define different levels of testing in more detail.

"},{"location":"v3/faq/#isnt-wordpress-untestable","title":"Isn't WordPress untestable?","text":"

No; it's sometimes difficult to test and not as straightforward as other PHP frameworks but it's definitely not untestable.

You are writing code that runs on WordPress, not the Core code for WordPress so the question should really be: will you write testable code?

It's up to you to decide at what level you want to make your code testable and how much you want to test it.

"},{"location":"v3/faq/#do-i-need-to-use-a-specific-local-development-environment-to-use-wp-browser","title":"Do I need to use a specific local development environment to use wp-browser?","text":"

No. I've started using wp-browser on a vanilla PHP built-in server to, then, move to MAMP (or XAMP) and, from there, to other solutions.

I've configured and used wp-browser on Docker, Vagrant, VVV, Valet and various CI solutions.

To this day I keep using different setups on different machines and personally prefer Docker for its portability.

"},{"location":"v3/faq/#can-i-only-test-plugins-with-wp-browser","title":"Can I only test plugins with wp-browser?","text":"

No, you can test any kind of WordPress application.

With \"application\" I mean any PHP software built on top of WordPress: plugins, themes, whole sites.

"},{"location":"v3/faq/#if-im-testing-a-site-do-i-have-to-use-the-default-wordpress-file-structure","title":"If I'm testing a site do I have to use the default WordPress file structure?","text":"

No, you can use any file structure you want.

Some wp-browser modules will need a little help to find your code but, so far, I've never been unable to set it up.

"},{"location":"v3/faq/#can-i-use-wp-browser-even-if-my-wordpress-application-doesnt-use-composer","title":"Can I use wp-browser even if my WordPress application doesn't use Composer?","text":"

Yes, although wp-browser, as a development tool, cannot be installed without Composer.

"},{"location":"v3/faq/#should-i-use-wp-browser-to-test-my-production-servers","title":"Should I use wp-browser to test my production servers?","text":"

No. Unless you know very well what you're doing that's a dangerous idea that might leave you with a broken site and an empty database.

As almost any testing tool, wp-browser should be used locally on local installations of WordPress that do not contain any valuable information.

"},{"location":"v3/faq/#how-can-i-avoid-the-wpdb-module-from-replacing-the-contents-of-my-database","title":"How can I avoid the WPDb module from replacing the contents of my database?","text":"

You should always backup any database that contains any information you care about before running any test.

You can read the answer to this question in the WPDb module documentation.

"},{"location":"v3/faq/#can-i-run-all-my-tests-with-one-command","title":"Can I run all my tests with one command?","text":"

Theoretically: yes, in practice: no.

When you use codecept run Codeception will run all the tests from all the suites.

This, done in the context of other frameworks, will generally not create any problem but, in the context of WordPress it will.

While handling a single HTTP request WordPress will set, and use, a number of constants and globals and, likewise, will do plugins and themes that follow WordPress standards.

This means that the global context (variable scope) will be left \"dirty\" and contain \"left-over\" constants and globals from the previous tests.

An example is one where a test for the handling of Ajax requests sets the DOING_AJAX constant: this will be now set for any test after the one that set it thus breaking, or worse altering, all the following ones.

So, in short, run each suite separately.

"},{"location":"v3/faq/#can-i-have-more-than-one-suite-of-one-kind","title":"Can I have more than one suite of one kind?","text":"

Yes, you should.

As an example you might have a frontend suite running acceptance tests on the site frontend and a backend suite running acceptance tests on the site backend.

Think of suites as a tool to organize your tests: there's a good measure between too organized and not organized at all.

"},{"location":"v3/faq/#ive-used-phpunit-before-for-my-unit-tests-can-i-reuse-that-knowledge-and-code-with-wp-browser","title":"I've used PHPUnit before for my unit tests, can I reuse that knowledge and code with wp-browser?","text":"

Yes.

Codeception uses PHPUnit as one of its main components and can run PHPUnit tests with little or no modification.

As such you can just move your existing PHPUnit tests in a dedicated suite and be ready to run in minutes.

"},{"location":"v3/faq/#ive-already-set-up-my-tests-to-run-using-the-core-phpunit-based-test-suite-can-i-keep-using-my-tests","title":"I've already set up my tests to run using the Core PHPUnit-based test suite, can I keep using my tests?","text":"

Yes.

Codeception uses PHPUnit as one of its main components and can run PHPUnit tests with little or no modification.

One of the goals of wp-browser was to make it easier to test WordPress application at an integration level (or \"WordPress unit\" level).

As such migrating those tests could be a matter of minutes requiring no modification to the tests if not for moving some files and creating a dedicated suite.

"},{"location":"v3/faq/#why-is-the-project-called-wp-browser","title":"Why is the project called wp-browser?","text":"

When I started working with Codeception to run my acceptance tests I kept creating steps that I would reuse over and over in my projects.

I packed them in a module extending the PHPBrowser module.

Being a natural talent in naming things I've called the module WPBrowser and published it. As I started relying on Codeception more and more I kept adding modules but the name remained.

"},{"location":"v3/installation/","title":"Installation","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/installation/#installation","title":"Installation","text":""},{"location":"v3/installation/#where-should-i-install-wp-browser","title":"Where should I install wp-browser?","text":"

As a rule-of-thumb wp-browser should be installed in the root folder of your project.

If your project is a plugin then it should be installed in the root folder of your plugin; if your project is a theme it should be installed in the root folder of your theme.

If your project is a site I'd, personally install it in the site root folder.

The purpose of installing wp-browser in the root folder of a project is to keep the code and its tests under version control together.

Exceptions apply but, for most projects, that's what I would do.

"},{"location":"v3/installation/#initializing-the-composer-project","title":"Initializing the Composer project","text":"

Since Composer is a requirement of wp-browser and the only way to install it you should, first thing, initialize the Composer project.

If you've already initialized the Composer project you can skip this section.

Once you've decided where to install wp-browser navigate to that folder using the terminal and type:

composer init\n

Composer will take you through a number of questions to setup some meta information about your project.

Do not install any dependency yet when asked (unless you know what you're doing) and, as a suggestion, set wordpress-plugin as \"Package Type\".

Also, since WordPress is licensed under the GPL-2.0+ you might want to set the \"License\" of your project to GPL-2.0-or-later.

"},{"location":"v3/installation/#installing-wp-browser-as-a-development-dependency","title":"Installing wp-browser as a development dependency","text":"

Once you've initialized the Composer project it's time to require wp-browser ; you can read more about the usage of the require command on the Composer documentation.

wp-browser is a testing tool and, as such, should be installed as a project development dependency, not as a normal (production) one.

From the terminal type:

composer require --dev lucatume/wp-browser\n

This will install the latest stable version of wp-browser and, along with it, Codeception and PHPUnit in the vendor folder of your project.

Once that's done it's time to move to the setup and configuration of wp-browser.

"},{"location":"v3/levels-of-testing/","title":"Levels of testing","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/levels-of-testing/#what-is-a-unit-test-an-acceptance-test","title":"What is a unit test? An acceptance test?","text":"

This page has no pretense to be THE source of truth about what is called how in the context of tests; the purpose of this page is to lay out the terminology that I'll use in the documentation to define the levels and component of testing. Wikipedia, forums and other documents online will offer alternate, and equally valid, definitions.

"},{"location":"v3/levels-of-testing/#the-signup-page-example","title":"The signup page example","text":"

Let's assume I'm testing a WordPress plugin that adds mailing list management and subscription functionalities to a site.

The plugin provides a number of functions and, among them, it will add a sign-up page to receive users applications.

"},{"location":"v3/levels-of-testing/#acceptance-tests","title":"Acceptance tests","text":"

In brief: make assertions as a user would.

The user might be tech-savvy as much as I want her to be but still make assertions only on what feedback the site provides.

The code below tests a user can subscribe to the mailing list:

<?php\n// UserSuccessfulSignupTest.php\n\n// Add a page that contains the shortcode that will render the signup form.\n$I->havePageInDatabase( [\n    'post_name' => 'signup',\n    'post_content'=> 'Sign-up for our awesome thing! [signup]',\n] );\n\n// Go to the page.\n$I->amOnPage( '/signup' );\n\n// Submit the form as a user would submit it. \n$I->submitForm( '#signup-form', [\n  'name' => 'Luca',\n  'email' => 'luca@theAverageDev.com',\n] );\n\n// Make sure I see a confirmation message. \n$I->waitForElement( '#signup-confirmation' );\n
"},{"location":"v3/levels-of-testing/#functional-tests","title":"Functional tests","text":"

In brief: make assertions as a developer would.

The test code below asserts front-end submissions are correctly processed from the developer perspective:

<?php\n// file tests/functional/SignupSubmissionCest.php\n\nclass SignupSubmissionCest {\n\n    public function _before( FunctionalTester $I ) {\n        // Add a page that contains the shortcode that will render the signup form.\n        $I->havePageInDatabase( [\n            'post_name' => 'signup',\n            'post_content'=> 'Sign-up for our awesome thing! [signup]',\n        ] );\n\n        $I->amOnPage( '/signup' );\n    }\n\n    public function test_good_signup( FunctionalTester $I ) {\n        $I->sendAjaxPostRequest( '/wp-json/acme/v1/signup', [\n          '_wpnonce' => $I->grabAttributeFrom( '#signup-nonce', 'value' ),\n          'name' => 'Luca',\n          'email' => 'luca@theAverageDev.com',\n        ] );\n\n        $I->seeResponseCodeIsSuccessful();\n        $I->seeUserInDatabase( [ 'user_login' => 'luca', 'user_email' => 'luca@theaveragedev.com' ] );\n    }\n\n    public function test_bad_email_signup( FunctionalTester $I ) {\n        $I->sendAjaxPostRequest( '/wp-json/acme/v1/signup', [\n          '_wpnonce' => $I->grabAttributeFrom( '#signup-nonce', 'value' ),\n          'name' => 'Luca',\n          'email' => 'not-really-an-email',\n        ] );\n\n        $I->seeResponseCodeIs( 400 );\n        $I->dontSeeUserInDatabase( [ 'user_login' => 'luca', 'user_email' => 'not-really-an-email' ] );\n    }\n}\n

The code looks, initially, like an acceptance test, but differs in its action and assertion phase: in place of filling a form and clicking \"Submit\" it sends a POST request to a REST API endpoint and checks the effect of the submission in the database.

All of these actions fall squarely into what a developer would do, not into what a user could/should be able to do.

Furthermore, the format of the test is not the same as the one used in the acceptance test.

The acceptance test is written in the most eloquent testing format supported by Codeception, the Cept format, this test uses a more PHPUnit-like format, the Cest format.

While the first is easier to skim for non-developers the second harnesses the power of a re-using pieces of code, the page creation and navigation in the example, to optimize the test code.

"},{"location":"v3/levels-of-testing/#integration-tests","title":"Integration tests","text":"

In brief: test code modules in the context of a WordPress website.

In this type of test the WordPress, and additional plugins code, is loaded in the same variable scope as the tests; this is why in the example below I'm using classes (WP_REST_Request, WP_REST_Response) and methods (register_rest_route) defined by WordPress, not the plugin code.

The REST API request sent by the application form will be handled by a class, Acme\\Signup\\SubmissionHandler, that's been attached to the /wp-json/acme/v1/signup path:

<?php\n// file src/rest.php\n\nadd_action( 'rest_api_init', function () {\n    register_rest_route( 'acme/v1', '/signup', array(\n        'methods' => 'POST',\n        'callback' => function( WP_Rest_Request $request ) {\n            $email_validator = new Acme\\Signup\\EmailValidator();\n            $handler = new Acme\\Signup\\SubmissionHandler( $email_validator );\n\n            return $handler->handle( $request );\n        },\n    ) );\n} );\n

I want to test the chain of classes and methods that's handling such a request in the context of a WordPress installation.

Integration is usually about testing \"modules\" of code: groups of classes and functions working together to provide a service or complete a task.

In the context of integration testing the class dependencies and/or the context are not mocked.

<?php\n// file tests/integration/SubmissionHandlingTest.php\n\nclass SubmissionHandlingTest extends \\Codeception\\TestCase\\WPTestCase {\n    public function test_good_request() {\n        $request = new WP_Rest_Request();\n        $request->set_body_params( [ 'name' => 'luca', 'email' => 'luca@theaveragedev.com' ] );\n        $handler = new  Acme\\Signup\\SubmissionHandler();\n\n        $response = $handler->handle( $request );\n\n        $this->assertIntsanceOf( WP_REST_Response::class, $response );\n        $this->assertEquals( 200, $response->get_status() );\n        $this->assertInstanceOf( Acme\\Signup\\Submission_Good::class, $handler->last_submission() );\n        $this->assertEquals( 'luca', $handler->last_submission()->name() );\n        $this->assertEquals( 'luca@theaveragedev.com', $handler->last_submission()->email() );\n    }\n\n    public function test_bad_email_request() {\n        $request = new WP_Rest_Request();\n        $request->set_body_params( [ 'name' => 'luca', 'email' => 'not-a-valid-email' ] );\n        $handler = new  Acme\\Signup\\SubmissionHandler();\n\n        $response = $handler->handle( $request );\n\n        $this->assertIntsanceOf( WP_REST_Response::class, $response );\n        $this->assertEquals( 400, $response->get_status() );\n        $this->assertInstanceOf( Acme\\Signup\\Submission_Bad::class, $handler->last_submission() );\n        $this->assertEquals( 'luca', $handler->last_submission()->name() );\n        $this->assertEquals( 'not-a-valid-email', $handler->last_submission()->email() );\n    }\n}\n

The test format used is the familiar PhpUnit one; the only difference is the base test class that's being extended (\\Codeception\\TestCase\\WPTestCase) is one provided by wp-browser.

In the context of WordPress \"integration\" might also mean testing that filters used by the code have the expected effect.

"},{"location":"v3/levels-of-testing/#unit-tests","title":"Unit tests","text":"

In brief: test single classes or functions in isolation.

The email address is validated by the Acme\\Signup\\EmailValidator class.

In the test code below I want to make sure the validation works as intended.

<?php\n// file tests/unit/EmailValidatorTest.php\n\nclass EmailValidatorTest extends Codeception\\Test\\Test {\n    public function test_good_email_validation() {\n        $validator = new Acme\\Signup\\EmailValidator();\n\n        $this->assertTrue( $validator->validate( 'luca@theaveragedev.com' ) ); \n    }\n\n    public function test_bad_email_validation(){\n        $validator = new Acme\\Signup\\EmailValidator();\n\n        $this->assertTrue( $validator->validate( 'not-an-email' ) );\n    }\n\n    public function test_tricky_email_validation() {\n        $validator = new Acme\\Signup\\EmailValidator();\n\n        $this->assertTrue( $validator->validate( 'luca+signup@theaveragedev.com' ) ); \n    }\n\n    public function test_validation_with_service(){\n        // Stub the validation service.\n        $validation_service = $this->prophesize( Acme\\Signup\\ValidationService::class );\n        $validation_service->validate( 'luca@theaveragedev.com' )->willReturn( true );\n        $validation_service->validate( 'lucas@theaveragedev.com' )->willReturn( false );\n        // Build the validator and set it to use the mock validation service.\n        $validator = new Acme\\Signup\\EmailValidator();\n        $validator->use_service( $validation_service->reveal() );\n\n        $this->assertTrue( $validator->validate( 'luca@theaveragedev.com' ) );\n        $this->assertFalse( $validator->validate( 'lucas@theaveragedev.com' ) );\n    }\n}\n

Unit tests is where stubbing/mocking/spying of dependencies is used to gain total control over the input and context the class is using.

In the last test method I'm doing exactly that testing the email validator with an external validation service.

In the example I'm using the Prophecy mock engine that comes with PHPUnit along with its own mocking/stubbing/spying solutions.

There are other mocking engines (e.g Mockery) that could be used.

"},{"location":"v3/levels-of-testing/#wordpress-unit-tests","title":"WordPress \"unit\" tests","text":"

In brief: test single classes or functions that require WordPress code in as much isolation as possible.

This is what most people referring to \"unit tests\" in the context of WordPress is talking about.

The purpose of this kind of tests is to test one class of a WordPress application, or one function, that requires a WordPress-defined function or class with a unit testing approach.

In the example below I'm testing the Acme\\Signup\\SubmissionHandler class on a \"unit\" level making sure it will mark a request as bad if the email is not a valid one.

<?php\n// file tests/unit/SubmissionHandlerTest.php\nclass SubmissionHandlerTest extends Codeception\\Test\\Test {\n    protected  $request;\n    protected $validator;\n\n    public function setUp() {\n        // Mock the request.\n        $this->request = $this->prophesize( WP_REST_Request::class );\n        // Spy on the validator.\n        $this->validator = $this->prophesize( Acme\\Signup\\EmailValidator::class );\n    }\n\n    public function test_email_is_validated_by_default() {\n        $this->request->get_param( 'name' )->willReturn( 'luca' );\n        $this->request->get_param( 'email' )->willReturn( 'luca@theaveragedev.com' );\n\n        $handler = new Acme\\Signup\\SubmissionHandler( $this->validator->reveal() );\n        $handler->set_validator( $this->validator );\n        $response = $handler->handle( $this->request->reveal() );\n\n        $this->assertInstanceOf( WP_REST_Response::class, $response );\n        // Verify on the validator spy.\n        $this->validator->validate( 'luca@theaveragedev.com' )->shouldHaveBeenCalled();\n    }\n\n    public function test_will_not_validate_email_if_missing() {\n        $this->request->get_param( 'name' )->willReturn( 'luca' );\n        $this->request->get_param( 'email' )->willReturn( '' );\n\n        $handler = new Acme\\Signup\\SubmissionHandler( $this->validator->reveal() );\n        $handler->set_validator( $this->validator );\n        $response = $handler->handle( $this->request->reveal() );\n\n        $this->assertInstanceOf( WP_REST_Response::class, $response );\n        // Verify on the validator spy.\n        $this->validator->validate( Argument::any() )->shouldNotHaveBeenCalled();\n    }\n}\n

The class uses the WP_REST_Request and WP_Rest_Response classes as input and output and will probably, internally, use more functions defined by WordPress.

One solution to avoid loading WordPress, could be to rewrite test versions of each and all the WordPress functions and classes needed by all the classes I want to unit test; this would require updating each time the classes requirements change.

Furthermore internationalization (e.g. __()) and filtering (e.g apply_filters) functions would not need to be mocked if not in specific cases and would pretty much be copy and paste versions of the WordPres ones.

Loading single pieces of WordPress is a dangerous and brittle endeavour and it's not supported by the framework.

To avoid all this WordPress \"unit tests\" pay the price of having to bootstrap WordPress, thus requiring a database connection.

This kind of test setup and level is the one you can see in the PHPUnit Core suite of WordPress itself.

"},{"location":"v3/requirements/","title":"Requirements","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/requirements/#requirements","title":"Requirements","text":"

wp-browser has some requirements your development environment will need to fulfill for it to work correctly.

"},{"location":"v3/requirements/#php","title":"PHP","text":"

The minimum supported version of PHP supported by wp-browser is 5.6.

This requirement does not reflect on the minimum PHP version your plugin might require; see the FAQs for more information.

"},{"location":"v3/requirements/#composer","title":"Composer","text":"

There is no phar version of wp-browser and it can only be installed using Composer.

See Composer installation guide for more information.

"},{"location":"v3/requirements/#wordpress-mysql-apachenginx","title":"WordPress, MySQL, Apache/Nginx","text":"

wp-browser will not download, install and configure WordPress for you.

It will also not download, install and setup MySQL, Apache, Nginx or any other technology required by a fully functional WordPress installation for you.

You need to set up a local WordPress installation on your own; you can use your preferred solution to do it.

In the documentation I will show automated ways to do this but, for most projects, that's not the best solution.

"},{"location":"v3/setting-up-minimum-wordpress-installation/","title":"Setting up a minimum WordPress installation","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/setting-up-minimum-wordpress-installation/#setting-up-a-minimum-wordpress-installation","title":"Setting up a minimum WordPress installation","text":"

As mentioned in Installation section wp-browser will not download, configure and install WordPress for you.

On a high level, once WordPress is installed and configured, whatever local development environment solution you've used, there are some information you'll need to gather before moving into wp-browser configuration.

While there will be a section dedicated to different environments and setups I will outline below the example setup I will use, in the next section, to configure wp-browser:

  • WordPress is installed, on my machine, at /Users/luca/Sites/wordpress.
  • I'm running MySQL server locally; I can connect to the MySQL server with the command mysql -u root -h 127.0.0.1 -P 3306; there is no password.
  • I've created two databases, wordpress and tests, with the command:
    mysql -u root -h 127.0.0.1 -P 3306 -e \"create database if not exists wordpress; create database if not exists tests\"\n
  • I've configured the /Users/luca/Sites/wordpress/wp-config.php file like below (redacted for brevity):
    <?php\ndefine( 'DB_NAME', 'wordpress' );\ndefine( 'DB_USER', 'root' );\ndefine( 'DB_PASSWORD', '' );\ndefine( 'DB_HOST', '127.0.0.1' );\ndefine( 'DB_CHARSET', 'utf8' );\ndefine( 'DB_COLLATE', '' );\n\n$table_prefix = 'wp_';\n\nif ( ! defined( 'ABSPATH' ) )\n    define( 'ABSPATH', dirname( __FILE__ ) . '/' );\n\nrequire_once ABSPATH . 'wp-settings.php';\n
  • To serve the site I'm using PHP built-in server with the command:
    (cd /Users/luca/Sites/wordpress; php -S localhost:8080)\n
  • I can access the WordPress homepage at http://localhost:8080 and the administration area at http://localhost:8080/wp-admin.
  • I've installed WordPress via its UI (http://localhost:8080/wp-admin), the administrator username is admin, the administrator password is password.
  • I'm testing a plugin and that plugin is in the folder, relative to the WordPress root folder, wp-content/plugins/acme-plugin.

With all the steps above done I can now move into the actual wp-browser configuration phase.

"},{"location":"v3/advanced/run-in-separate-process/","title":"Running tests in separate processes","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/advanced/run-in-separate-process/#running-tests-in-separate-processes","title":"Running tests in separate processes","text":"

PHPUnit offers the possibility to run tests in a separate PHP process; Codeception does not officially support the option as of version 4.0.

The wp-browser project tries to fill that gap by supporting the @runInSeparateProcess annotation. This support comes with some caveats, though:

  1. The support is only for test cases extending the Codeception\\TestCase\\WPTestCase class (the base test case for integration or \"WordPress unit\" tests)
  2. The support wp-browser provides only supports the @preserveGlobalState annotation with the disabled value; this means there is no support for preserving global state between tests.

Read more about what this means in PHPUnit documentation.

"},{"location":"v3/advanced/run-in-separate-process/#why-run-tests-in-a-separate-php-process","title":"Why run tests in a separate PHP process?","text":"

One main reason: isolation.

What does \"isolation\" means?

Before answering that question, it's essential to understand, via an example, why a lack of isolation might be an issue.

I want to test the get_api function. The function will return the correct singleton instance of an API handling class: an instance of Api when the function is called in non-admin context, and an instance of AdminApi when the function is called in admin context. The get_api function is acting as a service locator.

<?php\nfunction get_api(){\n    static $api;\n\n    if(null !== $api){\n        return $api;\n    }\n\n    if( is_admin() ) {\n        $api = new Admin_Api();\n    } else {\n        $api = new Api();\n    }\n\n    return $api;\n}\n

There are two challenges to testing this function:

  1. The is_admin function, defined by WordPress, looks up a WP_ADMIN constant to know if the context of the current request is an administration UI one or not.
  2. The get_api function will check for the context and resolve and build the correct instance only once, the first time it's called in the context of a request.

There are some possible solutions to this problem:

a. Refactor the get_api function into a method of an Api_Factory object taking the context as a dependency, thus allowing injection of the \"context\" (which implies the creation of a Context adapter that will proxy its is_admin method to the is_admin function). You can find the code for such refactoring in the OOP refactoring of get_api section. b. Refactor the get_api function to accept the current is_admin value as an input argument, get_api( $is_admin ), this refactoring moves part of the complexity of getting hold of the correct instance of the API handler on the client code. Adding more build condition and checks, e.g., if the current request is a REST request or not or some tests on the user authorizations, then, requires adding more input arguments to the get_api function: the knowledge of the implementation of the get_api method will \"leak\" to the client code having to replicate complexity throughout the system.

I want to layout possible solutions to the problem to show there is always a design alternative to make code testable that might or might not fit the current time or scope constraint.

In this example, I've inherited the get_api function from the existing code, and it cannot be changed, yet I want to test it dealing with the two problems outlined above.

"},{"location":"v3/advanced/run-in-separate-process/#running-tests-in-separate-php-processes","title":"Running tests in separate PHP processes","text":"

To test the get_api function shown above I've created a new wpunit type of test:

vendor/bin/codecept g:wpunit integration \"api\"\n

The command scaffolds a test/integration/apiTest.php file that I've modified to ensure full coverage of the get_api function:

<?php\n\nclass apiTest extends \\Codeception\\TestCase\\WPTestCase\n{\n    public function test_get_api_exists()\n    {\n        $this->assertTrue(function_exists('get_api'));\n    }\n\n    public function test_get_api_will_cache()\n    {\n        $this->assertSame(get_api(), get_api());\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function test_get_api_will_return_api_if_not_admin()\n    {\n        // Let's make sure we're NOT in admin context.\n        define('WP_ADMIN', false);\n\n        $api = get_api();\n\n        $this->assertInstanceOf(Api::class, $api);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function test_get_api_will_cache_api_if_not_admin()\n    {\n        // Let's make sure we're NOT in admin context.\n        define('WP_ADMIN', false);\n\n        $api = get_api();\n\n        $this->assertSame(get_api(), $api);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function test_get_api_will_return_api_if_is_admin()\n    {\n        // Let's make sure we're NOT in admin context.\n        define('WP_ADMIN', true);\n\n        $api = get_api();\n\n        $this->assertInstanceOf(AdminApi::class, $api);\n    }\n\n    /**\n     * @runInSeparateProcess\n     * @preserveGlobalState disabled\n     */\n    public function test_get_api_will_cache_api_if_is_admin()\n    {\n        // Let's make sure we're NOT in admin context.\n        define('WP_ADMIN', true);\n\n        $api = get_api();\n\n        $this->assertSame(get_api(), $api);\n    }\n}\n

Some pieces of this code are worth pointing out:

  1. There are two test methods, test_get_api_exists and test_get_api_will_cache that are not running in a separate process. Running tests in a separate process provide isolation at the cost of speed, only tests that require isolation should run in a separate PHP process.
  2. I instruct the Codeception and PHPUnit test runner to run a test method in a different process by adding two annotations that are both required ** precisely as shown**:
    /**\n * @runInSeparateProcess\n * @preserveGlobalState disabled\n */\n
  3. The isolation part of this testing approach shines through when I define, in the last four tests, the WP_ADMIN constant multiple times. If I try to do that in test code running in the same PHP process, then the second define call would cause a fatal error.
  4. The isolation has also taken care of the second issue where the get_api function caches the $api instance after its first resolution in a static variable: since each test happens in a self-contained, dedicated PHP process, the static $api variable will be null at the start of each test.
"},{"location":"v3/advanced/run-in-separate-process/#can-i-run-some-tests-in-the-same-process-and-some-in-a-separate-process","title":"Can I run some tests in the same process and some in a separate process?","text":"

Yes. In the example test code in the previous section, the test_get_api_exists and test_get_api_will_cache test methods are not running in separate processes.

In your test cases extending the Codeception\\TestCase\\WPTestCase, you can mix test methods running in the primary PHP process and those running in a separate PHP process without issues.

"},{"location":"v3/advanced/run-in-separate-process/#oop-refactoring-of-get_api","title":"OOP refactoring of get_api","text":"

In the Why run tests in a separate PHP process? section I've outlined a possible refactoring of the get_api function to make it testable without requiring the use of separate PHP processes.

I'm providing this refactoring code below for the sake of completeness, the judgment of which approach is \"better\" is up to the reader.

<?php\n\nclass Context_Adapter{\n\n    public function is_admin(){\n        return \\is_admin();\n    }\n\n}\n\nclass Api_Factory{\n\n    private $api;\n    private $context;\n\n    public function __construct(Context_Adapter $context){\n        $this->context = $context;\n    }\n\n    public function getApi(){\n        if(null !== $this->api){\n            return $this->api;    \n        }\n\n        if($this->context->is_admin()){\n            $api = new Admin_Api;\n        } else {\n            $api = new Api;\n        }\n\n        return $api;\n    }\n}\n

Now the Api_Factory class can be injected by injecting a mocked Context_Adapter class, modifying the return value of the Context_Adapter::is_admin method.

Due to the supposed requirement of the API instance being a singleton, this solution will also require some container or service-locator to ensure at most only one instance of the Api_Factory exists at any given time in the context of a request.

"},{"location":"v3/migration/from-version-2-to-version-3/","title":"Version 2 to version 3","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/migration/from-version-2-to-version-3/#migrating-projects-from-version-2-of-wp-browser-to-version-3","title":"Migrating projects from version 2 of wp-browser to version 3","text":"

Version 3 of wp-browser removed, to allow for broader compatibility with PHP and Composer versions, some of its dependencies and modified some of its methods. Here is a list of changes and the suggested courses of action:

  • Removed symfony/process to launch and manage external processes; re-add it your project development requirements using composer require --dev symfony/process.
  • Removed the wp-cli/wp-cli-bundle dependency; if you were relying on non-core packages, then re-add it to your project development requirements using composer require --dev wp-cli/wp-cli-bundle.
  • Removed the WithWpCli::executeBackgroundWpCliCommand trait method, and, as a consequence, the WPCLI::executeBackgroundWpCliCommand module method; you could have used the latter, if this was the case, then require the symfony/process as explained above and launch processes in background using its API; find out more.
  • Refactored the WPCLI module to build and escape string command lines differently; the handling of command-line arguments for the WPCLI module has been modified to make it a bit more consistent and robust; as a consequence, you might experience some breakages in string commands that used to work correctly before; should this be the case then either modify your code to provide the command in array format (taking care of the correct escaping in your code), or make sure to pass a correctly structured command string to the WPCLI module.
"},{"location":"v3/modules/WPBrowser/","title":"WPBrowser","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/modules/WPBrowser/#wpbrowser-module","title":"WPBrowser module","text":"

This module should be used in acceptance and functional tests, see levels of testing for more information.

This module extends the PHPBrowser module adding WordPress-specific configuration parameters and methods.

The module simulates a user interaction with the site without Javascript support; if you need to test your project with Javascript support use the WPWebDriver module.

"},{"location":"v3/modules/WPBrowser/#module-requirements-for-codeception-40","title":"Module requirements for Codeception 4.0+","text":"

This module requires the codeception/module-phpbrowser Composer package to work when wp-browser is used with Codeception 4.0.

To install the package run:

composer require --dev codeception/module-phpbrowser:^1.0\n
"},{"location":"v3/modules/WPBrowser/#configuration","title":"Configuration","text":"

Since this module extends the PHPBrowser module provided by Codeception, please refer to the PHPBrowser configuration section for more information about the base configuration parameters.

  • url required - Start URL of your WordPress project, e.g. http://wp.test.
  • headers - Default headers are set before each test; this might be useful to simulate a specific user agent during the tests or to identify the request source. Note that the headers defined in the config should be prefaced with HTTP_ in your wp-config.php file. This can be used to select which database to use.
  • handler (default: curl) - The Guzzle handler to use. By default curl is used, also possible to pass stream, or any valid class name as Handler.
  • middleware - The Guzzle middlewares to add. An array of valid callables is required; see here for more information.
  • curl - curl options; only applied if using the curl handler; more options are available.
  • adminUsername required - This is the login name, not the \"nice\" name, of the administrator user of the WordPress test site. This will be used to fill the username field in WordPress login page.
  • adminPassword required - This is the the password of the administrator use of the WordPress test site. This will be used to fill the password in WordPress login page.
  • adminPath required - The path, relative to the WordPress test site home URL, to the administration area, usually /wp-admin.
"},{"location":"v3/modules/WPBrowser/#example-configuration","title":"Example configuration","text":"
  modules:\n      enabled:\n          - WPBrowser\n      config:\n          WPBrowser:\n              url: 'http://wordpress.localhost'\n              adminUsername: 'admin'\n              adminPassword: 'password'\n              adminPath: '/wp-admin'\n              headers:\n                X_TEST_REQUEST: 1\n                X_WPBROWSER_REQUEST: 1\n

Read here how to use the headers information to automatically change the database during acceptance and functional tests.

"},{"location":"v3/modules/WPBrowser/#public-api","title":"Public API","text":"
  • activatePlugin($pluginSlug) : void In the plugin administration screen activates a plugin clicking the \"Activate\" link.

The method will not handle authentication to the admin area.

  • activateTheme($slug) : void Activates a theme.

The method will not handle authentication and navigation to the themes administration page.

  • amEditingPostWithId($id) : void Go to the admin page to edit the post with the specified ID.

The method will not handle authentication the admin area.

  • amEditingUserWithId($id) : void Go to the admin page to edit the user with the specified ID.

The method will not handle authentication the admin area.

  • amHttpAuthenticated($username, $password) : void

  • amOnAdminAjaxPage([$queryVars]) : void Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.

The method will not handle authentication, nonces or authorization.

  • amOnAdminPage($page) : void Go to a page in the admininstration area of the site.

This method will not handle authentication to the administration area.

  • amOnCronPage([$queryVars]) : void Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

  • amOnPage($page) : void

  • amOnPagesPage() : void Go the \"Pages\" administration screen.

The method will not handle authentication.

  • amOnPluginsPage() : void Go to the plugins administration screen.

The method will not handle authentication.

  • amOnSubdomain($subdomain) : void

  • amOnThemesPage() : void Moves to the themes administration page.

  • amOnUrl($url) : void

  • attachFile($field, $filename) : void

  • checkOption($option) : void

  • click($link, [$context]) : void

  • deactivatePlugin($pluginSlug) : void In the plugin administration screen deactivate a plugin clicking the \"Deactivate\" link.

The method will not handle authentication and navigation to the plugins administration page.

  • deleteHeader($name) : void Deletes the header with the passed name. Subsequent requests will not have the deleted header in its request.

Example:

<?php\n$I->haveHttpHeader('X-Requested-With', 'Codeception');\n$I->amOnPage('test-headers.php');\n// ...\n$I->deleteHeader('X-Requested-With');\n$I->amOnPage('some-other-page.php');\n

  • dontSee($text, [$selector]) : void

  • dontSeeCheckboxIsChecked($checkbox) : void

  • dontSeeCookie($cookie, [array $params]) : void

  • dontSeeCurrentUrlEquals($uri) : void

  • dontSeeCurrentUrlMatches($uri) : void

  • dontSeeElement($selector, [$attributes]) : void

  • dontSeeInCurrentUrl($uri) : void

  • dontSeeInField($field, $value) : void

  • dontSeeInFormFields($formSelector, array $params) : void

  • dontSeeInSource($raw) : void

  • dontSeeInTitle($title) : void

  • dontSeeLink($text, [$url]) : void

  • dontSeeOptionIsSelected($selector, $optionText) : void

  • dontSeePluginInstalled($pluginSlug) : void Assert a plugin is not installed in the plugins administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

  • dontSeeResponseCodeIs($code) : void Checks that response code is equal to value provided.
<?php\n$I->dontSeeResponseCodeIs(200);\n\n// recommended \\Codeception\\Util\\HttpCode\n$I->dontSeeResponseCodeIs(\\Codeception\\Util\\HttpCode::OK);\n
  • executeInGuzzle(Closure $function) : void Low-level API method. If Codeception commands are not enough, use Guzzle HTTP Client methods directly

Example:

<?php\n$I->executeInGuzzle(function (\\GuzzleHttp\\Client $client) {\n     $client->get('/get', ['query' => ['foo' => 'bar']]);\n});\n?>\n

It is not recommended to use this command on a regular basis. If Codeception lacks important Guzzle Client methods, implement them and submit patches.

  • fillField($field, $value) : void

  • followRedirect() : void Follow pending redirect if there is one.

<?php\n$I->followRedirect();\n
  • grabActiveTheme() : void Returns the slug of the currently active themes.

The method will not handle authentication and navigation to the themes administration page.

  • grabAttributeFrom($cssOrXpath, $attribute) : void

  • grabAvailableThemes([$classes]) : void Returns the list of available themes.

The method will not handle authentication and navigation to the themes administration page.

  • grabCookie($cookie, [array $params]) : void

  • grabCookiesWithPattern($cookiePattern) : void Returns all the cookies whose name matches a regex pattern.

  • grabFromCurrentUrl([$uri]) : void

  • grabMultiple($cssOrXpath, [$attribute]) : void

  • grabPageSource() : void Grabs current page source code.

  • grabTextFrom($cssOrXPathOrRegex) : void

  • grabValueFrom($field) : void

  • grabWordPressTestCookie([$name]) : void Returns WordPress default test cookie object if present.

  • haveHttpHeader($name, $value) : void Sets the HTTP header to the passed value - which is used on subsequent HTTP requests through PhpBrowser.

Example:

<?php\n$I->haveHttpHeader('X-Requested-With', 'Codeception');\n$I->amOnPage('test-headers.php');\n

To use special chars in Header Key use HTML Character Entities: Example: Header with underscore - 'Client_Id' should be represented as - 'Client_Id' or 'Client_Id'

<?php\n$I->haveHttpHeader('Client&#95;Id', 'Codeception');\n
  • haveServerParameter($name, $value) : void Sets SERVER parameter valid for all next requests.
$I->haveServerParameter('name', 'value');\n
  • logOut([$redirectTo]) : void Navigate to the default WordPress logout page and click the logout link.

  • loginAs($username, $password) : void Login as the specified user.

The method will not follow redirection, after the login, to any page.

  • loginAsAdmin() : void Login as the administrator user using the credentials specified in the module configuration.

The method will not follow redirection, after the login, to any page.

  • makeHtmlSnapshot([$name]) : void

  • moveBack([$numberOfSteps]) : void Moves back in history.

  • resetCookie($cookie, [array $params]) : void

  • see($text, [$selector]) : void

  • seeCheckboxIsChecked($checkbox) : void

  • seeCookie($cookie, [array $params]) : void

  • seeCurrentUrlEquals($uri) : void

  • seeCurrentUrlMatches($uri) : void

  • seeElement($selector, [$attributes]) : void

  • seeErrorMessage([$classes]) : void In an administration screen look for an error admin notice.

The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

  • seeInCurrentUrl($uri) : void

  • seeInField($field, $value) : void

  • seeInFormFields($formSelector, array $params) : void

  • seeInSource($raw) : void

  • seeInTitle($title) : void

  • seeLink($text, [$url]) : void

  • seeMessage([$classes]) : void In an administration screen look for an admin notice.

The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

  • seeNumberOfElements($selector, $expected) : void

  • seeOptionIsSelected($selector, $optionText) : void

  • seePageNotFound() : void Asserts that current page has 404 response status code.

  • seePluginActivated($pluginSlug) : void Assert a plugin is activated in the plugin administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

  • seePluginDeactivated($pluginSlug) : void Assert a plugin is not activated in the plugins administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

  • seePluginInstalled($pluginSlug) : void Assert a plugin is installed, no matter its activation status, in the plugin administration screen.

The method will not handle authentication and navigation to the plugin administration screen.

  • seeResponseCodeIs($code) : void Checks that response code is equal to value provided.
<?php\n$I->seeResponseCodeIs(200);\n\n// recommended \\Codeception\\Util\\HttpCode\n$I->seeResponseCodeIs(\\Codeception\\Util\\HttpCode::OK);\n
  • seeResponseCodeIsBetween($from, $to) : void Checks that response code is between a certain range. Between actually means [from <= CODE <= to]

  • seeResponseCodeIsClientError() : void Checks that the response code is 4xx

  • seeResponseCodeIsRedirection() : void Checks that the response code 3xx

  • seeResponseCodeIsServerError() : void Checks that the response code is 5xx

  • seeResponseCodeIsSuccessful() : void Checks that the response code 2xx

  • seeThemeActivated($slug) : void Verifies that a theme is active.

The method will not handle authentication and navigation to the themes administration page.

  • seeWpDiePage() : void Checks that the current page is one generated by the wp_die function.

The method will try to identify the page based on the default WordPress die page HTML attributes.

  • selectOption($select, $option) : void

  • sendAjaxGetRequest($uri, [$params]) : void Sends an ajax GET request with the passed parameters. See sendAjaxPostRequest()

  • sendAjaxPostRequest($uri, [$params]) : void Sends an ajax POST request with the passed parameters. The appropriate HTTP header is added automatically: X-Requested-With: XMLHttpRequest Example:

    <?php\n$I->sendAjaxPostRequest('/add-task', ['task' => 'lorem ipsum']);\n
    Some frameworks (e.g. Symfony) create field names in the form of an \"array\": <input type=\"text\" name=\"form[task]\"> In this case you need to pass the fields like this:
    <?php\n$I->sendAjaxPostRequest('/add-task', ['form' => [\n    'task' => 'lorem ipsum',\n    'category' => 'miscellaneous',\n]]);\n

  • sendAjaxRequest($method, $uri, [$params]) : void Sends an ajax request, using the passed HTTP method. See sendAjaxPostRequest() Example:

    <?php\n$I->sendAjaxRequest('PUT', '/posts/7', ['title' => 'new title']);\n

  • setCookie($name, $val, [array $params]) : void

  • setHeader($name, $value) : void Alias to haveHttpHeader

  • setMaxRedirects($maxRedirects) : void Sets the maximum number of redirects that the Client can follow.

<?php\n$I->setMaxRedirects(2);\n
  • setServerParameters(array $params) : void Sets SERVER parameters valid for all next requests. this will remove old ones.
$I->setServerParameters([]);\n
  • startFollowingRedirects() : void Enables automatic redirects to be followed by the client.
<?php\n$I->startFollowingRedirects();\n
  • stopFollowingRedirects() : void Prevents automatic redirects to be followed by the client.
<?php\n$I->stopFollowingRedirects();\n
  • submitForm($selector, array $params, [$button]) : void

  • switchToIframe($name) : void Switch to iframe or frame on the page.

Example:

<iframe name=\"another_frame\" src=\"http://example.com\">\n

<?php\n# switch to iframe\n$I->switchToIframe(\"another_frame\");\n
  • uncheckOption($option) : void

This class extends \\Codeception\\Module\\PhpBrowser

This class implements \\Codeception\\Lib\\Interfaces\\MultiSession, \\Codeception\\Lib\\Interfaces\\Remote, \\Codeception\\Lib\\Interfaces\\Web, \\Codeception\\Lib\\Interfaces\\PageSourceSaver, \\Codeception\\Lib\\Interfaces\\ElementLocator, \\Codeception\\Lib\\Interfaces\\ConflictsWithModule

"},{"location":"v3/modules/WPCLI/","title":"WPCLI","text":"

This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

"},{"location":"v3/modules/WPCLI/#wpcli-module","title":"WPCLI module","text":"

This module should be used in acceptance and functional tests to setup, or verify, tests pre and post conditions using WP-CLI commands. This module allows invoking WP-CLI commands, refer to the official site for more information.

The module will use its own version of WP-CLI, not the one installed in the machine running the tests!

By default, wp-browser will only include the wp-cli/wp-cli package; this package contains the basic files to run WP-CLI and does not contain all the commands that come with a typical wp-cli installation. If, in your tests, you require all the commands that usually come installed with WP-CLI, then you should require the wp-cli/wp-cli-bundle package as a development dependency of your project, see below.

"},{"location":"v3/modules/WPCLI/#fixing-not-a-registered-command-issue","title":"Fixing \"not a registered command\" issue","text":"

To keep the conflicts at a manageable level, the wp-browser project does not include all the commands WP-CLI usually comes bundled with. Running, in the context of an automated test, a WP-CLI command that would work on your machine, e.g. wp plugin list --status=active, will not work on a default installation of wp-browser and you will get the following error message:

[ModuleException] WPCLI: wp-cli terminated with status [1] and output [Error: 'plugin' is not a registered wp command. See 'wp help' for available commands.]\n

To resolve the message just add the package you require as a development dependency or add the whole WP-CLI bundle:

composer require --dev wp-cli/wp-cli-bundle\n

The package will make all the default WP-CLI commands available to the WP-CLI version used in tests.

"},{"location":"v3/modules/WPCLI/#module-requirements-for-codeception-40","title":"Module requirements for Codeception 4.0+","text":"

This module requires the codeception/module-cli Composer package to work when wp-browser is used with Codeception 4.0.

To install the package run:

composer require --dev codeception/module-cli:^1.0\n
"},{"location":"v3/modules/WPCLI/#detecting-requests-coming-from-this-module","title":"Detecting requests coming from this module","text":"

When it runs this module will set the WPBROWSER_HOST_REQUEST environment variable. You can detect and use that information to, as an example, use the correct database in your test site wp-config.php file:

<?php\nif ( \n    // Custom header.\n    isset( $_SERVER['HTTP_X_TESTING'] )\n    // Custom user agent.\n    || ( isset( $_SERVER['HTTP_USER_AGENT'] ) && $_SERVER['HTTP_USER_AGENT'] === 'wp-browser' )\n    // The env var set by the WPClIr or WordPress modules.\n    || getenv( 'WPBROWSER_HOST_REQUEST' )\n) {\n    // Use the test database if the request comes from a test.\n    define( 'DB_NAME', 'wordpress_test' );\n} else {\n    // Else use the default one.\n    define( 'DB_NAME', 'wordpress' );\n}\n

"},{"location":"v3/modules/WPCLI/#configuration","title":"Configuration","text":"
  • path required - the absolute, or relative, path to the WordPress root folder. This will be mapped to the --path argument of the wp-cli binary.
  • throw - defaults to true to throw an exception when a wp-cli command does not return an exit status of 0; if set to false then the exit status of the commands will be returned as is.
  • timeout - defaults to 60 (seconds) to set each process execution timeout to a certain value; set to null, false or 0 to disable timeout completely.

Additionally the module configuration will forward any configuration parameter to wp-cli as a flag or option. In the example configuration below the allow-root flag and the some-option option will be passed to wp-cli directly and prepended to the command as global options.

Note: these extract configuration flags and options will be prepended to all commands executed by wp-cli!

"},{"location":"v3/modules/WPCLI/#environment-configuration","title":"Environment configuration","text":"

The wp-cli binary supports a set of environment variables to modify its behavior.

These environment variables can be set on the commands ran by the WPCLI module using the optional env array in the module configuration. The example configuration below shows all of them with some example values. Most of the times you won't need any of these, but they are there for more fine-grained control over the module operations.

The module is not validating the environment variables in any way! Those values will be evaluated by wp-cli at runtime and might generate errors if not correctly configured.

"},{"location":"v3/modules/WPCLI/#example-configuration","title":"Example configuration","text":"
modules:\n    enabled:\n        - WPCLI\n    config:\n        WPCLI:\n            path: /Users/Luca/Sites/wp\n            throw: true\n            timeout: 60\n            # This will be prepended to the command, `wp --allow-root <command>`.\n            allow-root: true\n            # This will be prepended to the command, `wp --some-option=some-value <command>`.\n            some-option: some-value\n            env:\n                # Any one of these, if provided, will be set as environment variable for the the cli command process. \n                # See https://make.wordpress.org/cli/handbook/config/#environment-variables for information.\n                # Equivalent to `WP_CLI_STRICT_ARGS_MODE=1 wp <command>'.\n                strict-args: true\n                # Equivalent to `WP_CLI_CACHE_DIR=/tmp/wp-cli-cache wp <command>'.\n                cache-dir: '/tmp/wp-cli-cache'\n                # Equivalent to `WP_CLI_CONFIG_PATH=/app/public wp <command>'.\n                config-path: '/app/public'\n                # Equivalent to `WP_CLI_CUSTOM_SHELL=/bin/zsh wp <command>'.\n                custom-shell: '/bin/zsh'\n                # Equivalent to `WP_CLI_DISABLE_AUTO_CHECK_UPDATE=1 wp <command>'.\n                disable-auto-update: true\n                # Equivalent to `WP_CLI_PACKAGES_DIR=/wp-cli/packages wp <command>'.\n                packages-dir: '/wp-cli/packages'\n                # Equivalent to `WP_CLI_PHP=/usr/local/bin/php/7.2/php wp <command>'.\n                php: '/usr/local/bin/php/7.2/php'\n                # Equivalent to `WP_CLI_PHP_ARGS='foo=bar some=23' wp <command>'.\n                php-args: 'foo=bar some=23'\n
"},{"location":"v3/modules/WPCLI/#public-api","title":"Public API","text":"
  • buildFullCommand
  • cli
  • cliToArray
  • cliToString
  • dontSeeInShellOutput
  • seeInShellOutput
  • seeResultCodeIs
  • seeResultCodeIsNot
  • seeShellOutputMatches
buildFullCommand

Builds the full command to run including the PHP binary and the wp-cli boot file path.

// This method is defined in the WithWpCli trait.\n  // Set the wp-cli path, `$this` is a test case.\n  $this->setUpWpCli( '/var/www/html' );\n  // Builds the full wp-cli command, including the `path` variable.\n  $fullCommand =  $this->buildFullCommand(['core', 'version']);\n  // The full command can then be used to run it with another process handler.\n  $wpCliProcess = new Process($fullCommand);\n  $wpCliProcess->run();\n
Parameters
  • \\Codeception\\Module\\array/string $command - The command to run. cli

    Executes a wp-cli command targeting the test WordPress installation. minus wp. For back-compatibility purposes you can still pass the commandline as a string, but the array format is the preferred and supported method.

    // Activate a plugin via wp-cli in the test WordPress site.\n  $I->cli(['plugin', 'activate', 'my-plugin']);\n  // Change a user password.\n  $I->cli(['user', 'update', 'luca', '--user_pass=newpassword']);\n
    Parameters
    • string/string/\\Codeception\\Module\\array $userCommand - The string of command and parameters as it would be passed to wp-cli cliToArray

      Returns the output of a wp-cli command as an array optionally allowing a callback to process the output. minus wp. For back-compatibility purposes you can still pass the commandline as a string, but the array format is the preferred and supported method.

      // Return a list of inactive themes, like ['twentyfourteen', 'twentyfifteen'].\n  $inactiveThemes = $I->cliToArray(['theme', 'list', '--status=inactive', '--field=name']);\n  // Get the list of installed plugins and only keep the ones starting with \"foo\".\n  $fooPlugins = $I->cliToArray(['plugin', 'list', '--field=name'], function($output){\n  return array_filter(explode(PHP_EOL, $output), function($name){\n  return strpos(trim($name), 'foo') === 0;\n  });\n  });\n
      Parameters
      • string/string/\\Codeception\\Module\\array $userCommand - The string of command and parameters as it would be passed to wp-cli
      • \\callable $splitCallback - An optional callback function to split the results array.
      • cliToString

        Returns the output of a wp-cli command as a string. minus wp. For back-compatibility purposes you can still pass the commandline as a string, but the array format is the preferred and supported method.

        // Return the current site administrator email, using string command format.\n  $adminEmail = $I->cliToString('option get admin_email');\n  // Get the list of active plugins in JSON format, two ways.\n  $activePlugins = $I->cliToString(['plugin', 'list','--status=active', '--format=json']);\n  $activePlugins = $I->cliToString(['option', 'get', 'active_plugins' ,'--format=json']);\n
        Parameters
        • string/\\Codeception\\Module\\array $userCommand - The string of command and parameters as it would be passed to wp-cli dontSeeInShellOutput

          Checks that output from last command doesn't contain text.

          // Return the current site administrator email, using string command format.\n  $I->cli('plugin list --status=active');\n  $I->dontSeeInShellOutput('my-inactive/plugin.php');\n
          Parameters
          • string $text - The text to assert is not in the output.
          seeInShellOutput

          Checks that output from last command contains text.

          // Return the current site administrator email, using string command format.\n  $I->cli('option get admin_email');\n
          Parameters
          • string $text - The text to assert is in the output.
          seeResultCodeIs

          Checks the result code from the last command.

          // Return the current site administrator email, using string command format.\n  $I->cli('option get admin_email');\n  $I->seeResultCodeIs(0);\n
          Parameters
          • int $code - The desired result code.
          seeResultCodeIsNot

          Checks the result code from the last command.

          // Return the current site administrator email, using string command format.\n  $I->cli('invalid command');\n  $I->seeResultCodeIsNot(0);\n
          Parameters
          • int $code - The result code the command should not have exited with.
          seeShellOutputMatches

          Checks that output from the last command matches a given regular expression.

          // Return the current site administrator email, using string command format.\n  $I->cli('option get admin_email');\n
          Parameters
          • string $regex - The regex pattern, including delimiters, to assert the output matches against.

          This class extends \\Codeception\\Module

          "},{"location":"v3/modules/WPDb/","title":"WPDb","text":"

          This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

          "},{"location":"v3/modules/WPDb/#wpdb-module","title":"WPDb module","text":"

          This module should be used in acceptance and functional tests, see levels of testing for more information. This module extends the Db module adding WordPress-specific configuration parameters and methods. The module provides methods to read, write and update the WordPress database directly, without relying on WordPress methods, using WordPress functions or triggering WordPress filters.

          "},{"location":"v3/modules/WPDb/#module-requirements-for-codeception-40","title":"Module requirements for Codeception 4.0+","text":"

          This module requires the codeception/module-db Composer package to work when wp-browser is used with Codeception 4.0.

          To install the package run:

          composer require --dev codeception/module-db:^1.0\n
          "},{"location":"v3/modules/WPDb/#backup-your-content","title":"Backup your content","text":"

          This module, like the Codeception Db one it extends, by default will load a database dump in the database it's using. This means that the database contents will be replaced by the dump contents on each run of a suite using the module. You can set the populate and cleanup parameters to false to prevent this default behavior but it's usually not what you need in an automated test. Make a backup of any database you're using in tests that contains any information you care about before you run any test!

          "},{"location":"v3/modules/WPDb/#change-the-database-used-depending-on-whether-youre-running-tests-or-not","title":"Change the database used depending on whether you're running tests or not","text":"

          The chore of having to plug different databases, or backup them, depending on whether you're manually testing the site or automatically testing can be mitigated switching them automatically depending on the browser user agent or request headers. This module was born to be used in acceptance and functional tests (see levels of testing for more information) and will often be coupled with modules like the WPBrowser one or the WPWebDriver one. Depending on which of the two modules is being used in the suite there are different ways to automate the \"database switching\".

          "},{"location":"v3/modules/WPDb/#automatically-changing-database-based-on-the-browser-user-agent","title":"Automatically changing database based on the browser user agent","text":"

          If you would like to automate the \"switching above\" below you will find an example setup. Update the test site wp-config.php file from this:

          define( 'DB_NAME', 'wordpress' );\n
          to this:
          <?php\nif ( \n    // Custom header.\n    isset( $_SERVER['HTTP_X_TESTING'] )\n    // Custom user agent.\n    || ( isset( $_SERVER['HTTP_USER_AGENT'] ) && $_SERVER['HTTP_USER_AGENT'] === 'wp-browser' )\n    // The env var set by the WPClIr or WordPress modules.\n    || getenv( 'WPBROWSER_HOST_REQUEST' )\n) {\n    // Use the test database if the request comes from a test.\n    define( 'DB_NAME', 'wordpress_test' );\n} else {\n    // Else use the default one.\n    define( 'DB_NAME', 'wordpress' );\n}\n

          If you're using the WPWebDriver module set the user agent in the browser, in this example I'm setting the user agent in Chromedriver:

          class_name: AcceptanceTester\nmodules:\n    enabled:\n        - \\Helper\\Acceptance\n        - WPDb\n        - WPWebDriver\n    config:\n        WPDb:\n            dsn: 'mysql:host=%WP_DB_HOST%;dbname=%WP_DB_NAME%'\n            user: %WP_DB_USER%\n            password: %WP_DB_PASSWORD%\n            dump: tests/_data/dump.sql\n            populate: true\n            cleanup: false\n            url: '%WP_URL%'\n            tablePrefix: %WP_TABLE_PREFIX%\n            urlReplacement: true\n        WPWebDriver:\n            url: '%WP_URL%'\n            adminUsername: '%WP_ADMIN_USERNAME%'\n            adminPassword: '%WP_ADMIN_PASSWORD%'\n            adminPath: '%WP_ADMIN_PATH%'\n            browser: chrome\n            host: localhost\n            port: 4444\n            window_size: false\n            wait: 5\n            capabilities:\n              \"goog:chromeOptions\":\n                args:\n                  - \"--headless\"\n                  - \"--disable-gpu\"\n                  - \"--disable-dev-shm-usage\"\n                  - \"--proxy-server='direct://'\"\n                  - \"--proxy-bypass-list=*\"\n                  - \"--no-sandbox\"\n

          If you're using the WPBrowser module send a specific header in the context of test requests:

          class_name: AcceptanceTester\nmodules:\n    enabled:\n        - \\Helper\\Acceptance\n        - WPDb\n        - WPBrowser\n    config:\n        WPDb:\n              dsn: 'mysql:host=%DB_HOST%;dbname=%WP_DB_NAME%'\n              user: %WP_DB_USER%\n              password: %WP_DB_PASSWORD%\n              dump: 'tests/_data/dump.sql'\n              populate: true\n              cleanup: true\n              reconnect: false\n              url: '%WP_URL%'\n              tablePrefix: 'wp_'\n        WPBrowser:\n              url: '%WP_URL%'\n              adminUsername: 'admin'\n              adminPassword: 'admin'\n              adminPath: '/wp-admin'\n              headers: \n                X-Testing: 'wp-browser'\n

          "},{"location":"v3/modules/WPDb/#configuration","title":"Configuration","text":"
          • dsn required - the database POD DSN connection details; read more on PHP PDO documentation. If the database is accessible (as is the case on the latest version of [Local by Flywheel][http://localwp.com]) via unix socket, then the string to insert here should look like this mysql:unix_socket=/path/to/the/mysql.sock;dbname=wordpress.
          • user required - the database user.
          • password required - the database password.
          • url required - the full URL, including the HTTP scheme, of the website whose database is being accessed. WordPress uses hard-codece URLs in the database, that URL will be set by this module when applying the SQL dump file during population or cleanup.
          • dump required - defaults to null; sets the path, relative to the project root folder, or absolute to the SQL dump file that will be used to set the tests initial database fixture. If set to null then the populate, cleanup and populator parameters will be ignored.
          • populate - defaults to true to empty the target database and import the SQL dump(s) specified in the dump argument before the test suite is started.
          • cleanup - defaults to true empty the target database and import the SQL dump(s) specified in the dump argument before each test.
          • urlReplacement - defaults to true to replace, while using the built-in, PHP-based, dump import solution the hard-coded WordPress URL in the database with the specified one.
          • originalUrl - specifies the original URL hard-coded into the version controlled SQL dump files. This can help prevent some URL replacement issues when the urlReplacement configuration parameter is set to true.
          • populator - defaults to null, if set to an executable shell command then that command will be used to populate the database in place of the built-in PHP solution; URL replacement will not apply in this case. Read more about this on Codeception documentation.
          • reconnect - defaults to true to force the module to reconnect to the database before each test in place of only connecting at the start of the tests.
          • waitlock - defaults to 10; wait lock (in seconds) that the database session should use for DDL statements.
          • tablePrefix - defaults to wp_; sets the prefix of the tables that the module will manipulate.
          • letAdminEmailVerification - defaults to an empty value to remove the Administrator Email Verification screen introduced in WordPress 5.3. Set to true to not remove the screen and show it when an administrator user first logs in.
          • letCron - defaults to an empty value to avoid wp-cron from being spawned during tests. Setting this to true will let wp-cron requests to fire during tests.
          "},{"location":"v3/modules/WPDb/#example-configuration","title":"Example configuration","text":"
          modules:\n  enabled:\n      - WPDb\n  config:\n      WPDb:\n          dsn: 'mysql:host=localhost;dbname=wordpress'\n          user: 'root'\n          password: 'password'\n          dump: 'tests/_data/dump.sql'\n          populate: true\n          cleanup: true\n          waitlock: 10\n          url: 'http://wordpress.localhost'\n          urlReplacement: true\n          tablePrefix: 'wp_'\n
          "},{"location":"v3/modules/WPDb/#using-the-module-with-the-wploader-one","title":"Using the module with the WPLoader one","text":"

          This module is often used in conjunction with the WPLoader one to use WordPress-defined functions, classes and methods in acceptance or functional tests. The WPLoader module should be set to only load WordPress and this module should be listed, in the modules.enabled section of the suite configuration file before the WPLoader one:

          modules:\n  enabled:\n      - WPDb # this before...\n      - WPLoader # ...this one.\n  config:\n      WPDb:\n        # ...\n      WPLoader:\n        loadOnly: true\n        # ... \n
          This will avoid issues where the WPLoader module could exit, terminating the test run, due to an inconsistent database state.

          "},{"location":"v3/modules/WPDb/#public-api","title":"Public API","text":"
          • countRowsInDatabase
          • dontHaveAttachmentFilesInDatabase
          • dontHaveAttachmentInDatabase
          • dontHaveBlogInDatabase
          • dontHaveCommentInDatabase
          • dontHaveCommentMetaInDatabase
          • dontHaveInDatabase
          • dontHaveLinkInDatabase
          • dontHaveOptionInDatabase
          • dontHavePostInDatabase
          • dontHavePostMetaInDatabase
          • dontHavePostThumbnailInDatabase
          • dontHaveSiteOptionInDatabase
          • dontHaveSiteTransientInDatabase
          • dontHaveTableInDatabase
          • dontHaveTermInDatabase
          • dontHaveTermMetaInDatabase
          • dontHaveTermRelationshipInDatabase
          • dontHaveTermTaxonomyInDatabase
          • dontHaveTransientInDatabase
          • dontHaveUserInDatabase
          • dontHaveUserInDatabaseWithEmail
          • dontHaveUserMetaInDatabase
          • dontSeeAttachmentInDatabase
          • dontSeeBlogInDatabase
          • dontSeeCommentInDatabase
          • dontSeeCommentMetaInDatabase
          • dontSeeLinkInDatabase
          • dontSeeOptionInDatabase
          • dontSeePageInDatabase
          • dontSeePostInDatabase
          • dontSeePostMetaInDatabase
          • dontSeePostWithTermInDatabase
          • dontSeeSiteOptionInDatabase
          • dontSeeTableInDatabase
          • dontSeeTermInDatabase
          • dontSeeTermMetaInDatabase
          • dontSeeTermTaxonomyInDatabase
          • dontSeeUserInDatabase
          • dontSeeUserMetaInDatabase
          • getSiteDomain
          • getUsersTableName
          • grabAllFromDatabase
          • grabAttachmentAttachedFile
          • grabAttachmentMetadata
          • grabBlogDomain
          • grabBlogPath
          • grabBlogTableName
          • grabBlogTableNames
          • grabBlogTablePrefix
          • grabBlogVersionsTableName
          • grabBlogsTableName
          • grabCommentmetaTableName
          • grabCommentsTableName
          • grabLatestEntryByFromDatabase
          • grabLinksTableName
          • grabOptionFromDatabase
          • grabPostMetaFromDatabase
          • grabPostmetaTableName
          • grabPostsTableName
          • grabPrefixedTableNameFor
          • grabRegistrationLogTableName
          • grabSignupsTableName
          • grabSiteMetaTableName
          • grabSiteOptionFromDatabase
          • grabSiteTableName
          • grabSiteTransientFromDatabase
          • grabSiteUrl
          • grabTablePrefix
          • grabTermIdFromDatabase
          • grabTermMetaTableName
          • grabTermRelationshipsTableName
          • grabTermTaxonomyIdFromDatabase
          • grabTermTaxonomyTableName
          • grabTermsTableName
          • grabUserIdFromDatabase
          • grabUserMetaFromDatabase
          • grabUsermetaTableName
          • grabUsersTableName
          • haveAttachmentInDatabase
          • haveBlogInDatabase
          • haveCommentInDatabase
          • haveCommentMetaInDatabase
          • haveLinkInDatabase
          • haveManyBlogsInDatabase
          • haveManyCommentsInDatabase
          • haveManyLinksInDatabase
          • haveManyPostsInDatabase
          • haveManyTermsInDatabase
          • haveManyUsersInDatabase
          • haveMenuInDatabase
          • haveMenuItemInDatabase
          • haveOptionInDatabase
          • havePageInDatabase
          • havePostInDatabase
          • havePostThumbnailInDatabase
          • havePostmetaInDatabase
          • haveSiteOptionInDatabase
          • haveSiteTransientInDatabase
          • haveTermInDatabase
          • haveTermMetaInDatabase
          • haveTermRelationshipInDatabase
          • haveTransientInDatabase
          • haveUserCapabilitiesInDatabase
          • haveUserInDatabase
          • haveUserLevelsInDatabase
          • haveUserMetaInDatabase
          • importSql
          • importSqlDumpFile
          • seeAttachmentInDatabase
          • seeBlogInDatabase
          • seeCommentInDatabase
          • seeCommentMetaInDatabase
          • seeLinkInDatabase
          • seeOptionInDatabase
          • seePageInDatabase
          • seePostInDatabase
          • seePostMetaInDatabase
          • seePostWithTermInDatabase
          • seeSiteOptionInDatabase
          • seeSiteSiteTransientInDatabase
          • seeTableInDatabase
          • seeTermInDatabase
          • seeTermMetaInDatabase
          • seeTermRelationshipInDatabase
          • seeTermTaxonomyInDatabase
          • seeUserInDatabase
          • seeUserMetaInDatabase
          • useBlog
          • useMainBlog
          • useTheme
          countRowsInDatabase

          Returns the number of table rows matching a criteria.

          $I->haveManyPostsInDatabase(3, ['post_status' => 'draft' ]);\n  $I->haveManyPostsInDatabase(3, ['post_status' => 'private' ]);\n  // Make sure there are now the expected number of draft posts.\n  $postsTable = $I->grabPostsTableName();\n  $draftsCount = $I->countRowsInDatabase($postsTable, ['post_status' => 'draft']);\n
          Parameters
          • string $table - The table to count the rows in.
          • array/\\Codeception\\Module\\array/array $criteria - Search criteria, if empty all table rows will be counted. dontHaveAttachmentFilesInDatabase

            Removes all the files attached with an attachment post, it will not remove the database entries. Requires the WPFilesystem module to be loaded in the suite.

            $posts = $I->grabPostsTableName();\n  $attachmentIds = $I->grabColumnFromDatabase($posts, 'ID', ['post_type' => 'attachment']);\n  // This will only remove the files, not the database entries.\n  $I->dontHaveAttachmentFilesInDatabase($attachmentIds);\n
            Parameters
            • \\Codeception\\Module\\array/int $attachmentIds - An attachment post ID or an array of attachment post IDs. dontHaveAttachmentInDatabase

              Removes an attachment from the posts table. table. the suite.

              $postmeta = $I->grabpostmetatablename();\n  $thumbnailId = $I->grabFromDatabase($postmeta, 'meta_value', [\n  'post_id' => $id,\n  'meta_key'=>'thumbnail_id'\n  ]);\n  // Remove only the database entry (including postmeta) but not the files.\n  $I->dontHaveAttachmentInDatabase($thumbnailId);\n  // Remove the database entry (including postmeta) and the files.\n  $I->dontHaveAttachmentInDatabase($thumbnailId, true, true);\n
              Parameters
              • \\Codeception\\Module\\array/array $criteria - An array of search criteria to find the attachment post in the posts
              • bool $purgeMeta - If set to true then the meta for the attachment will be purged too.
              • bool $removeFiles - Remove all files too, requires the WPFilesystem module to be loaded in
              • dontHaveBlogInDatabase

                Removes one ore more blogs from the database.

                // Remove the blog, all its tables and files.\n  $I->dontHaveBlogInDatabase(['path' => 'test/one']);\n  // Remove the blog entry, not the tables though.\n  $I->dontHaveBlogInDatabase(['blog_id' => $blogId]);\n  // Remove multiple blogs.\n  $I->dontHaveBlogInDatabase(['domain' => 'test']);\n
                Parameters
                • \\Codeception\\Module\\array/array $criteria - An array of search criteria to find the blog rows in the blogs table.
                • bool $removeTables - Remove the blog tables.
                • bool $removeUploads - Remove the blog uploads; requires the WPFilesystem module.
                • dontHaveCommentInDatabase

                  Removes an entry from the comments table.

                  $I->dontHaveCommentInDatabase(['comment_post_ID' => 23, 'comment_url' => 'http://example.copm']);\n
                  Parameters
                  • \\Codeception\\Module\\array/array $criteria - An array of search criteria.
                  • bool $purgeMeta - If set to true then the meta for the comment will be purged too.
                  • dontHaveCommentMetaInDatabase

                    Removes a post comment meta from the database

                    // Remove all meta for the comment with an ID of 23.\n  $I->dontHaveCommentMetaInDatabase(['comment_id' => 23]);\n  // Remove the `count` comment meta for the comment with an ID of 23.\n  $I->dontHaveCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'count']);\n
                    Parameters
                    • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontHaveInDatabase

                      Deletes a database entry. criteria.

                      $I->dontHaveInDatabase('custom_table', ['book_ID' => 23, 'book_genre' => 'fiction']);\n
                      Parameters
                      • string $table - The table name.
                      • \\Codeception\\Module\\array/array $criteria - An associative array of the column names and values to use as deletion dontHaveLinkInDatabase

                        Removes a link from the database.

                        $I->dontHaveLinkInDatabase(['link_url' => 'http://example.com']);\n
                        Parameters
                        • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontHaveOptionInDatabase

                          Removes an entry from the options table.

                          // Remove the `foo` option.\n  $I->dontHaveOptionInDatabase('foo');\n  // Remove the 'bar' option only if it has the `baz` value.\n  $I->dontHaveOptionInDatabase('bar', 'baz');\n
                          Parameters
                          • string $key - The option name.
                          • mixed/null $value - If set the option will only be removed if its value matches the passed one.
                          dontHavePostInDatabase

                          Removes an entry from the posts table.

                          $posts = $I->haveManyPostsInDatabase(3, ['post_title' => 'Test {{n}}']);\n  $I->dontHavePostInDatabase(['post_title' => 'Test 2']);\n
                          Parameters
                          • \\Codeception\\Module\\array/array $criteria - An array of search criteria.
                          • bool $purgeMeta - If set to true then the meta for the post will be purged too.
                          • dontHavePostMetaInDatabase

                            Removes an entry from the postmeta table.

                            $postId = $I->havePostInDatabase(['meta_input' => ['rating' => 23]]);\n  $I->dontHavePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'rating']);\n
                            Parameters
                            • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontHavePostThumbnailInDatabase

                              Remove the thumbnail (featured image) from a post, if any. Please note: the method will NOT remove the attachment post, post meta and file.

                              $attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));\n  $postId = $I->havePostInDatabase();\n  // Attach the thumbnail to the post.\n  $I->havePostThumbnailInDatabase($postId, $attachmentId);\n  // Remove the thumbnail from the post.\n  $I->dontHavePostThumbnailInDatabase($postId);\n
                              Parameters
                              • int $postId - The post ID to remove the thumbnail (featured image) from.
                              dontHaveSiteOptionInDatabase

                              Removes a site option from the database.

                              // Remove the `foo_count` option.\n  $I->dontHaveSiteOptionInDatabase('foo_count');\n  // Remove the `foo_count` option only if its value is `23`.\n  $I->dontHaveSiteOptionInDatabase('foo_count', 23);\n
                              Parameters
                              • string $key - The option name.
                              • mixed/null $value - If set the option will only be removed it its value matches the specified one.
                              dontHaveSiteTransientInDatabase

                              Removes a site transient from the database.

                              $I->dontHaveSiteTransientInDatabase(['my_plugin_site_buffer']);\n
                              Parameters
                              • string $key - The name of the transient to delete.
                              dontHaveTableInDatabase

                              Removes a table from the database. The case where a table does not exist is handled without raising an error.

                              $ordersTable = $I->grabPrefixedTableNameFor('orders');\n  $I->dontHaveTableInDatabase($ordersTable);\n
                              Parameters
                              • string $fullTableName - The full table name, including the table prefix.
                              dontHaveTermInDatabase

                              Removes a term from the database.

                              $I->dontHaveTermInDatabase(['name' => 'romance']);\n  $I->dontHaveTermInDatabase(['slug' => 'genre--romance']);\n
                              Parameters
                              • \\Codeception\\Module\\array/array $criteria - An array of search criteria.
                              • bool $purgeMeta - Whether the terms meta should be purged along side with the meta or not.
                              • dontHaveTermMetaInDatabase

                                Removes a term meta from the database.

                                // Remove the \"karma\" key.\n  $I->dontHaveTermMetaInDatabase(['term_id' => $termId, 'meta_key' => 'karma']);\n  // Remove all meta for the term.\n  $I->dontHaveTermMetaInDatabase(['term_id' => $termId]);\n
                                Parameters
                                • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontHaveTermRelationshipInDatabase

                                  Removes an entry from the term_relationships table.

                                  // Remove the relation between a post and a category.\n  $I->dontHaveTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $ttaxId]);\n  // Remove all terms for a post.\n  $I->dontHaveTermMetaInDatabase(['object_id' => $postId]);\n
                                  Parameters
                                  • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontHaveTermTaxonomyInDatabase

                                    Removes an entry from the term_taxonomy table.

                                    // Remove a specific term from the genre taxonomy.\n  $I->dontHaveTermTaxonomyInDatabase(['term_id' => $postId, 'taxonomy' => 'genre']);\n  // Remove all terms for a taxonomy.\n  $I->dontHaveTermTaxonomyInDatabase(['taxonomy' => 'genre']);\n
                                    Parameters
                                    • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontHaveTransientInDatabase

                                      Removes a transient from the database.

                                      // Removes the `tweets` transient from the database, if set.\n  $I->dontHaveTransientInDatabase('tweets');\n
                                      Parameters
                                      • string $transient - The name of the transient to delete.
                                      dontHaveUserInDatabase

                                      Removes a user from the database.

                                      $bob = $I->haveUserInDatabase('bob');\n  $alice = $I->haveUserInDatabase('alice');\n  // Remove Bob's user and meta.\n  $I->dontHaveUserInDatabase('bob');\n  // Remove Alice's user but not meta.\n  $I->dontHaveUserInDatabase($alice);\n
                                      Parameters
                                      • int/string $userIdOrLogin - The user ID or login name.
                                      • bool $purgeMeta - Whether the user meta should be purged alongside the user or not.
                                      dontHaveUserInDatabaseWithEmail

                                      Removes a user(s) from the database using the user email address.

                                      $luca = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);\n
                                      Parameters
                                      • string $userEmail - The email of the user to remove.
                                      • bool $purgeMeta - Whether the user meta should be purged alongside the user or not.
                                      dontHaveUserMetaInDatabase

                                      Removes an entry from the usermeta table.

                                      // Remove the `karma` user meta for a user.\n  $I->dontHaveUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);\n  // Remove all the user meta for a user.\n  $I->dontHaveUserMetaInDatabase(['user_id' => 23]);\n
                                      Parameters
                                      • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeAttachmentInDatabase

                                        Checks that an attachment is not in the database.

                                        $url = 'https://example.org/images/foo.png';\n  $I->dontSeeAttachmentInDatabase(['guid' => $url]);\n
                                        Parameters
                                        • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeBlogInDatabase

                                          Checks that a row is not present in the blogs table.

                                          $I->haveManyBlogsInDatabase(2, ['path' => 'test-{{n}}'], false)\n  $I->dontSeeBlogInDatabase(['path' => '/test-3/'])\n
                                          Parameters
                                          • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeCommentInDatabase

                                            Checks that a comment is not in the database. Will look up the \"comments\" table.

                                            // Checks for one comment.\n  $I->dontSeeCommentInDatabase(['comment_ID' => 23]);\n  // Checks for comments from a user.\n  $I->dontSeeCommentInDatabase(['user_id' => 89]);\n
                                            Parameters
                                            • \\Codeception\\Module\\array/array $criteria - The search criteria. dontSeeCommentMetaInDatabase

                                              Checks that a comment meta value is not in the database. Will look up the \"commentmeta\" table.

                                              // Delete a comment `karma` meta.\n  $I->dontSeeCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'karma']);\n  // Delete all meta for a comment.\n  $I->dontSeeCommentMetaInDatabase(['comment_id' => 23]);\n
                                              Parameters
                                              • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeLinkInDatabase

                                                Checks that a link is not in the links database table.

                                                $I->dontSeeLinkInDatabase(['link_url' => 'http://example.com']);\n  $I->dontSeeLinkInDatabase(['link_url' => 'http://example.com', 'link_name' => 'example']);\n
                                                Parameters
                                                • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeOptionInDatabase

                                                  Checks that an option is not in the database for the current blog. If the value is an object or an array then the serialized option will be checked.

                                                  $I->dontHaveOptionInDatabase('posts_per_page');\n  $I->dontSeeOptionInDatabase('posts_per_page');\n  $I->dontSeeOptionInDatabase('posts_per_page', 23);\n  $I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page']);\n  $I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page', 'option_value' => 23]);\n
                                                  Parameters
                                                  • \\Codeception\\Module\\array/string $criteriaOrName - An array of search criteria or the option name.
                                                  • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                  • dontSeePageInDatabase

                                                    Checks that a page is not in the database.

                                                    // Assert a page with an ID does not exist.\n  $I->dontSeePageInDatabase(['ID' => 23]);\n  // Assert a page with a slug and ID.\n  $I->dontSeePageInDatabase(['post_name' => 'test', 'ID' => 23]);\n
                                                    Parameters
                                                    • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeePostInDatabase

                                                      Checks that a post is not in the database.

                                                      // Asserts a post with title 'Test' is not in the database.\n  $I->dontSeePostInDatabase(['post_title' => 'Test']);\n  // Asserts a post with title 'Test' and content 'Test content' is not in the database.\n  $I->dontSeePostInDatabase(['post_title' => 'Test', 'post_content' => 'Test content']);\n
                                                      Parameters
                                                      • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeePostMetaInDatabase

                                                        Checks that a post meta value does not exist. If the meta value is an object or an array then the check will be made on its serialized version.

                                                        $postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']]);\n  $I->dontSeePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'woot']);\n
                                                        Parameters
                                                        • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeePostWithTermInDatabase

                                                          Checks that a post to term relation does not exist in the database. The method will check the \"term_relationships\" table.

                                                          $fiction = $I->haveTermInDatabase('fiction', 'genre');\n  $nonFiction = $I->haveTermInDatabase('non-fiction', 'genre');\n  $postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);\n  $I->dontSeePostWithTermInDatabase($postId, $nonFiction['term_taxonomy_id], );\n  passed this parameter will be interpreted as a `term_id`, else as a\n  the\n  term order.\n  to build a `taxonomy_term_id` from the `term_id`.\n
                                                          Parameters
                                                          • int $post_id - The post ID.
                                                          • int $term_taxonomy_id - The term term_id or term_taxonomy_id; if the $taxonomy argument is
                                                          • int/null $term_order - The order the term applies to the post, defaults to null to not use
                                                          • string/null $taxonomy - The taxonomy the term_id is for; if passed this parameter will be used
                                                          dontSeeSiteOptionInDatabase

                                                          Checks that a site option is not in the database.

                                                          // Check that the option is not set in the database.\n  $I->dontSeeSiteOptionInDatabase('foo_count');\n  // Check that the option is not set with a specific value.\n  $I->dontSeeSiteOptionInDatabase('foo_count', 23);\n  $I->dontSeeSiteOptionInDatabase(['option_name => 'foo_count', 'option_value' => 23]);\n
                                                          Parameters
                                                          • \\Codeception\\Module\\array/string $criteriaOrName - An array of search criteria or the option name.
                                                          • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                          • dontSeeTableInDatabase

                                                            Checks that a table is not in the database.

                                                            $options = $I->grabPrefixedTableNameFor('options');\n  $I->dontHaveTableInDatabase($options)\n  $I->dontSeeTableInDatabase($options);\n
                                                            Parameters
                                                            • string $table - The full table name, including the table prefix.
                                                            dontSeeTermInDatabase

                                                            Makes sure a term is not in the database. Looks up both the terms table and the term_taxonomy tables. and the term_taxonomy tables.

                                                            // Asserts a 'fiction' term is not in the database.\n  $I->dontSeeTermInDatabase(['name' => 'fiction']);\n  // Asserts a 'fiction' term with slug 'genre--fiction' is not in the database.\n  $I->dontSeeTermInDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);\n
                                                            Parameters
                                                            • \\Codeception\\Module\\array/array $criteria - An array of criteria to search for the term, can be columns from the terms dontSeeTermMetaInDatabase

                                                              Checks that a term meta is not in the database.

                                                              list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n  $I->haveTermMetaInDatabase($termId, 'rating', 4);\n  $I->dontSeeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'average_review']);\n
                                                              Parameters
                                                              • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeTermTaxonomyInDatabase

                                                                Checks that a term taxonomy is not in the database.

                                                                list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n  $I->dontSeeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'country']);\n
                                                                Parameters
                                                                • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeUserInDatabase

                                                                  Checks that a user is not in the database.

                                                                  // Asserts a user does not exist in the database.\n  $I->dontSeeUserInDatabase(['user_login' => 'luca']);\n  // Asserts a user with email and login is not in the database.\n  $I->dontSeeUserInDatabase(['user_login' => 'luca', 'user_email' => 'luca@theaveragedev.com']);\n
                                                                  Parameters
                                                                  • \\Codeception\\Module\\array/array $criteria - An array of search criteria. dontSeeUserMetaInDatabase

                                                                    Check that a user meta value is not in the database.

                                                                    // Asserts a user does not have a 'karma' meta assigned.\n  $I->dontSeeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);\n  // Asserts no user has any 'karma' meta assigned.\n  $I->dontSeeUserMetaInDatabase(['meta_key' => 'karma']);\n
                                                                    Parameters
                                                                    • \\Codeception\\Module\\array/array $criteria - An array of search criteria. getSiteDomain

                                                                      Returns the site domain inferred from the url set in the config.

                                                                      $domain = $I->getSiteDomain();\n  // We should be redirected to the HTTPS version when visiting the HTTP version.\n  $I->amOnPage('http://' . $domain);\n  $I->seeCurrentUrlEquals('https://' . $domain);\n
                                                                      getUsersTableName

                                                                      Returns the prefixed users table name.

                                                                      // Given a `wp_` table prefix returns `wp_users`.\n  $usersTable = $I->getUsersTableName();\n  // Given a `wp_` table prefix returns `wp_users`.\n  $I->useBlog(23);\n  $usersTable = $I->getUsersTableName();\n
                                                                      grabAllFromDatabase

                                                                      Returns all entries matching a criteria from the database.

                                                                      $books = $I->grabPrefixedTableNameFor('books');\n  $I->grabAllFromDatabase($books, 'title', ['genre' => 'fiction']);\n
                                                                      Parameters
                                                                      • string $table - The table to grab the values from.
                                                                      • string $column - The column to fetch.
                                                                      • \\Codeception\\Module\\array $criteria - The search criteria. grabAttachmentAttachedFile

                                                                        Returns the path, as stored in the database, of an attachment _wp_attached_file meta. The attached file is, usually, an attachment origal file.

                                                                        $file = $I->grabAttachmentAttachedFile($attachmentId);\n  $fileInfo = new SplFileInfo($file);\n  $I->assertEquals('jpg', $fileInfo->getExtension());\n
                                                                        Parameters
                                                                        • int $attachmentPostId - The attachment post ID.
                                                                        grabAttachmentMetadata

                                                                        Returns the metadata array for an attachment post. This is the value of the _wp_attachment_metadata meta.

                                                                        $metadata = $I->grabAttachmentMetadata($attachmentId);\n  $I->assertEquals(['thumbnail', 'medium', 'medium_large'], array_keys($metadata['sizes']);\n
                                                                        Parameters
                                                                        • int $attachmentPostId - The attachment post ID.
                                                                        grabBlogDomain

                                                                        Returns a blog domain given its ID.

                                                                        $blogIds = $I->haveManyBlogsInDatabase(3);\n  $domains = array_map(function($blogId){\n  return $I->grabBlogDomain($blogId);\n  }, $blogIds);\n
                                                                        Parameters
                                                                        • int $blogId - The blog ID.
                                                                        grabBlogPath

                                                                        Grabs a blog domain from the blogs table.

                                                                        $blogId = $I->haveBlogInDatabase('test');\n  $path = $I->grabBlogDomain($blogId);\n  $I->amOnSubdomain($path);\n  $I->amOnPage('/');\n
                                                                        Parameters
                                                                        • int $blogId - The blog ID.
                                                                        grabBlogTableName

                                                                        Returns the full name of a table for a blog from a multisite installation database.

                                                                        $blogOptionTable = $I->grabBlogTableName($blogId, 'option');\n
                                                                        Parameters
                                                                        • int $blogId - The blog ID.
                                                                        • string $table - The table name, without table prefix.
                                                                        grabBlogTableNames

                                                                        Returns a list of tables for a blog ID.

                                                                        $blogId = $I->haveBlogInDatabase('test');\n  $tables = $I->grabBlogTableNames($blogId);\n  $options = array_filter($tables, function($tableName){\n  return str_pos($tableName, 'options') !== false;\n  });\n
                                                                        Parameters
                                                                        • int $blogId - The ID of the blog to fetch the tables for.
                                                                        grabBlogTablePrefix

                                                                        Returns the table prefix for a blog.

                                                                        $blogId = $I->haveBlogInDatabase('test');\n  $blogTablePrefix = $I->getBlogTablePrefix($blogId);\n  $blogOrders = $I->blogTablePrefix . 'orders';\n
                                                                        Parameters
                                                                        • int $blogId - The blog ID.
                                                                        grabBlogVersionsTableName

                                                                        Gets the prefixed blog_versions table name.

                                                                        // Assuming a `wp_` table prefix it will return `wp_blog_versions`.\n  $blogVersionsTable = $I->grabBlogVersionsTableName();\n  $I->useBlog(23);\n  // Assuming a `wp_` table prefix it will return `wp_blog_versions`.\n  $blogVersionsTable = $I->grabBlogVersionsTableName();\n
                                                                        grabBlogsTableName

                                                                        Gets the prefixed blogs table name.

                                                                        // Assuming a `wp_` table prefix it will return `wp_blogs`.\n  $blogVersionsTable = $I->grabBlogsTableName();\n  $I->useBlog(23);\n  // Assuming a `wp_` table prefix it will return `wp_blogs`.\n  $blogVersionsTable = $I->grabBlogsTableName();\n
                                                                        grabCommentmetaTableName

                                                                        Returns the prefixed comment meta table name.

                                                                        // Get all the values of 'karma' for all comments.\n  $commentMeta = $I->grabCommentmetaTableName();\n  $I->grabAllFromDatabase($commentMeta, 'meta_value', ['meta_key' => 'karma']);\n
                                                                        grabCommentsTableName

                                                                        Gets the comments table name.

                                                                        // Will be `wp_comments`.\n  $comments = $I->grabCommentsTableName();\n  // Will be `wp_23_comments`.\n  $I->useBlog(23);\n  $comments = $I->grabCommentsTableName();\n
                                                                        grabLatestEntryByFromDatabase

                                                                        Returns the id value of the last table entry.

                                                                        $I->haveManyPostsInDatabase();\n  $postsTable = $I->grabPostsTableName();\n  $last = $I->grabLatestEntryByFromDatabase($postsTable, 'ID');\n  items.\n
                                                                        Parameters
                                                                        • string $tableName - The table to fetch the last insertion for.
                                                                        • string $idColumn - The column that is used, in the table, to uniquely identify
                                                                        grabLinksTableName

                                                                        Returns the prefixed links table name.

                                                                        // Given a `wp_` table prefix returns `wp_links`.\n  $linksTable = $I->grabLinksTableName();\n  // Given a `wp_` table prefix returns `wp_23_links`.\n  $I->useBlog(23);\n  $linksTable = $I->grabLinksTableName();\n
                                                                        grabOptionFromDatabase

                                                                        Gets an option value from the database.

                                                                        $count = $I->grabOptionFromDatabase('foo_count');\n
                                                                        Parameters
                                                                        • string $option_name - The name of the option to grab from the database.
                                                                        grabPostMetaFromDatabase

                                                                        Gets the value of one or more post meta values from the database.

                                                                        $thumbnail_id = $I->grabPostMetaFromDatabase($postId, '_thumbnail_id', true);\n
                                                                        Parameters
                                                                        • int $postId - The post ID.
                                                                        • string $metaKey - The key of the meta to retrieve.
                                                                        • bool $single - Whether to return a single meta value or an array of all available meta values.
                                                                        grabPostmetaTableName

                                                                        Returns the prefixed post meta table name.

                                                                        // Returns 'wp_postmeta'.\n  $I->grabPostmetaTableName();\n  // Returns 'wp_23_postmeta'.\n  $I->useBlog(23);\n  $I->grabPostmetaTableName();\n
                                                                        grabPostsTableName

                                                                        Gets the posts prefixed table name.

                                                                        // Given a `wp_` table prefix returns `wp_posts`.\n  $postsTable = $I->grabPostsTableName();\n  // Given a `wp_` table prefix returns `wp_23_posts`.\n  $I->useBlog(23);\n  $postsTable = $I->grabPostsTableName();\n
                                                                        grabPrefixedTableNameFor

                                                                        Returns a prefixed table name for the current blog. If the table is not one to be prefixed (e.g. users) then the proper table name will be returned.

                                                                        // Will return wp_users.\n  $usersTable = $I->grabPrefixedTableNameFor('users');\n  // Will return wp_options.\n  $optionsTable = $I->grabPrefixedTableNameFor('options');\n  // Use a different blog and get its options table.\n  $I->useBlog(2);\n  $blogOptionsTable = $I->grabPrefixedTableNameFor('options');\n
                                                                        Parameters
                                                                        • string $tableName - The table name, e.g. options.
                                                                        grabRegistrationLogTableName

                                                                        Gets the prefixed registration_log table name.

                                                                        // Assuming a `wp_` table prefix it will return `wp_registration_log`.\n  $blogVersionsTable = $I->grabRegistrationLogTableName();\n  $I->useBlog(23);\n  // Assuming a `wp_` table prefix it will return `wp_registration_log`.\n  $blogVersionsTable = $I->grabRegistrationLogTableName();\n
                                                                        grabSignupsTableName

                                                                        Gets the prefixed signups table name.

                                                                        // Assuming a `wp_` table prefix it will return `wp_signups`.\n  $blogVersionsTable = $I->grabSignupsTableName();\n  $I->useBlog(23);\n  // Assuming a `wp_` table prefix it will return `wp_signups`.\n  $blogVersionsTable = $I->grabSignupsTableName();\n
                                                                        grabSiteMetaTableName

                                                                        Gets the prefixed sitemeta table name.

                                                                        // Assuming a `wp_` table prefix it will return `wp_sitemeta`.\n  $blogVersionsTable = $I->grabSiteMetaTableName();\n  $I->useBlog(23);\n  // Assuming a `wp_` table prefix it will return `wp_sitemeta`.\n  $blogVersionsTable = $I->grabSiteMetaTableName();\n
                                                                        grabSiteOptionFromDatabase

                                                                        Gets a site option from the database.

                                                                        $fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');\n
                                                                        Parameters
                                                                        • string $key - The name of the option to read from the database.
                                                                        grabSiteTableName

                                                                        Gets the prefixed site table name.

                                                                        // Assuming a `wp_` table prefix it will return `wp_site`.\n  $blogVersionsTable = $I->grabSiteTableName();\n  $I->useBlog(23);\n  // Assuming a `wp_` table prefix it will return `wp_site`.\n  $blogVersionsTable = $I->grabSiteTableName();\n
                                                                        grabSiteTransientFromDatabase

                                                                        Gets a site transient from the database.

                                                                        $I->grabSiteTransientFromDatabase('total_comments');\n  $I->grabSiteTransientFromDatabase('api_data');\n
                                                                        Parameters
                                                                        • string $key - The site transient to fetch the value for, w/o the _site_transient_ prefix.
                                                                        grabSiteUrl

                                                                        Returns the current site URL as specified in the module configuration.

                                                                        $shopPath = $I->grabSiteUrl('/shop');\n
                                                                        Parameters
                                                                        • string $path - A path that should be appended to the site URL.
                                                                        grabTablePrefix

                                                                        Returns the table prefix, namespaced for secondary blogs if selected.

                                                                        // Assuming a table prefix of `wp_` it will return `wp_`;\n  $tablePrefix = $I->grabTablePrefix();\n  $I->useBlog(23);\n  // Assuming a table prefix of `wp_` it will return `wp_23_`;\n  $tablePrefix = $I->grabTablePrefix();\n
                                                                        grabTermIdFromDatabase

                                                                        Gets a term ID from the database. Looks up the prefixed terms table, e.g. wp_terms.

                                                                        // Return the 'fiction' term 'term_id'.\n  $termId = $I->grabTermIdFromDatabase(['name' => 'fiction']);\n  // Get a term ID by more stringent criteria.\n  $termId = $I->grabTermIdFromDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);\n  // Return the 'term_id' of the first term for a group.\n  $termId = $I->grabTermIdFromDatabase(['term_group' => 23]);\n
                                                                        Parameters
                                                                        • \\Codeception\\Module\\array/array $criteria - An array of search criteria. grabTermMetaTableName

                                                                          Gets the terms meta table prefixed name.

                                                                          // Returns 'wp_termmeta'.\n  $I->grabTermMetaTableName();\n  // Returns 'wp_23_termmeta'.\n  $I->useBlog(23);\n  $I->grabTermMetaTableName();\n
                                                                          grabTermRelationshipsTableName

                                                                          Gets the prefixed term relationships table name, e.g. wp_term_relationships.

                                                                          $I->grabTermRelationshipsTableName();\n
                                                                          grabTermTaxonomyIdFromDatabase

                                                                          Gets a term_taxonomy_id from the database. Looks up the prefixed terms_relationships table, e.g. wp_term_relationships.

                                                                          // Get the `term_taxonomy_id` for a term and a taxonomy.\n  $I->grabTermTaxonomyIdFromDatabase(['term_id' => $fictionId, 'taxonomy' => 'genre']);\n  // Get the `term_taxonomy_id` for the first term with a count of 23.\n  $I->grabTermTaxonomyIdFromDatabase(['count' => 23]);\n
                                                                          Parameters
                                                                          • \\Codeception\\Module\\array/array $criteria - An array of search criteria. grabTermTaxonomyTableName

                                                                            Gets the prefixed term and taxonomy table name, e.g. wp_term_taxonomy.

                                                                            // Returns 'wp_term_taxonomy'.\n  $I->grabTermTaxonomyTableName();\n  // Returns 'wp_23_term_taxonomy'.\n  $I->useBlog(23);\n  $I->grabTermTaxonomyTableName();\n
                                                                            grabTermsTableName

                                                                            Gets the prefixed terms table name, e.g. wp_terms.

                                                                            // Returns 'wp_terms'.\n  $I->grabTermsTableName();\n  // Returns 'wp_23_terms'.\n  $I->useBlog(23);\n  $I->grabTermsTableName();\n
                                                                            grabUserIdFromDatabase

                                                                            Gets the a user ID from the database using the user login.

                                                                            $userId = $I->grabUserIdFromDatabase('luca');\n
                                                                            Parameters
                                                                            • string $userLogin - The user login name.
                                                                            grabUserMetaFromDatabase

                                                                            Gets a user meta from the database.

                                                                            // Returns a user 'karma' value.\n  $I->grabUserMetaFromDatabase($userId, 'karma');\n  // Returns an array, the unserialized version of the value stored in the database.\n  $I->grabUserMetaFromDatabase($userId, 'api_data');\n
                                                                            Parameters
                                                                            • int $userId - The ID of th user to get the meta for.
                                                                            • string $meta_key - The meta key to fetch the value for.
                                                                            grabUsermetaTableName

                                                                            Returns the prefixed users meta table name.

                                                                            // Given a `wp_` table prefix returns `wp_usermeta`.\n  $usermetaTable = $I->grabUsermetaTableName();\n  // Given a `wp_` table prefix returns `wp_usermeta`.\n  $I->useBlog(23);\n  $usermetaTable = $I->grabUsermetaTableName();\n
                                                                            grabUsersTableName

                                                                            Returns the prefixed users table name.

                                                                            // Given a `wp_` table prefix returns `wp_users`.\n  $usersTable = $I->grabUsersTableName();\n  // Given a `wp_` table prefix returns `wp_users`.\n  $I->useBlog(23);\n  $usersTable = $I->grabUsersTableName();\n
                                                                            haveAttachmentInDatabase

                                                                            Creates the database entries representing an attachment and moves the attachment file to the right location. timestamp that should be used to build the \"year/time\" uploads sub-folder structure. override the image sizes created by default.

                                                                            $file = codecept_data_dir('images/test.png');\n  $attachmentId = $I->haveAttachmentInDatabase($file);\n  $image = codecept_data_dir('images/test-2.png');\n  $lastWeekAttachment = $I->haveAttachmentInDatabase($image, '-1 week');\n  Requires the WPFilesystem module.\n
                                                                            Parameters
                                                                            • string $file - The absolute path to the attachment file.
                                                                            • string/string/int $date - Either a string supported by the strtotime function or a UNIX
                                                                            • array/\\Codeception\\Module\\array/array $overrides - An associative array of values overriding the default ones.
                                                                            • \\Codeception\\Module\\array> $imageSizes - An associative array in the format [ => [,]] to haveBlogInDatabase

                                                                              Inserts a blog in the blogs table.

                                                                              // Create the `test` subdomain blog.\n  $blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId]);\n  // Create the `/test` subfolder blog.\n  $blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId], false);\n  or subfolder (`true`)\n
                                                                              Parameters
                                                                              • string $domainOrPath - The subdomain or the path to the be used for the blog.
                                                                              • array/\\Codeception\\Module\\array/array $overrides - An array of values to override the defaults.
                                                                              • bool $subdomain - Whether the new blog should be created as a subdomain (true)
                                                                              • haveCommentInDatabase

                                                                                Inserts a comment in the database.

                                                                                $I->haveCommentInDatabase($postId, ['comment_content' => 'Test Comment', 'comment_karma' => 23]);\n
                                                                                Parameters
                                                                                • int $comment_post_ID - The id of the post the comment refers to.
                                                                                • array/\\Codeception\\Module\\array/array $data - The comment data overriding default and random generated values. haveCommentMetaInDatabase

                                                                                  Inserts a comment meta field in the database. Array and object meta values will be serialized.

                                                                                  $I->haveCommentMetaInDatabase($commentId, 'api_ID', 23);\n  // The value will be serialized.\n  $apiData = ['ID' => 23, 'user' => 89, 'origin' => 'twitter'];\n  $I->haveCommentMetaInDatabase($commentId, 'api_data', $apiData);\n
                                                                                  Parameters
                                                                                  • int $comment_id - The ID of the comment to insert the meta for.
                                                                                  • string $meta_key - The key of the comment meta to insert.
                                                                                  • mixed $meta_value - The value of the meta to insert, if serializable it will be serialized.
                                                                                  haveLinkInDatabase

                                                                                  Inserts a link in the database.

                                                                                  $linkId = $I->haveLinkInDatabase(['link_url' => 'http://example.org']);\n
                                                                                  Parameters
                                                                                  • array/\\Codeception\\Module\\array/array $overrides - The data to insert. haveManyBlogsInDatabase

                                                                                    Inserts many blogs in the database. by the count.

                                                                                    $blogIds = $I->haveManyBlogsInDatabase(3, ['domain' =>'test-{{n}}']);\n  foreach($blogIds as $blogId){\n  $I->useBlog($blogId);\n  $I->haveManuPostsInDatabase(3);\n  }\n
                                                                                    Parameters
                                                                                    • int $count - The number of blogs to create.
                                                                                    • array/\\Codeception\\Module\\array/array $overrides - An array of values to override the default ones; {{n}} will be replaced
                                                                                    • bool $subdomain - Whether the new blogs should be created as a subdomain or subfolder.
                                                                                    • haveManyCommentsInDatabase

                                                                                      Inserts many comments in the database.

                                                                                      // Insert 3 random comments for a post.\n  $I->haveManyCommentsInDatabase(3, $postId);\n  // Insert 3 random comments for a post.\n  $I->haveManyCommentsInDatabase(3, $postId, ['comment_content' => 'Comment {{n}}']);\n
                                                                                      Parameters
                                                                                      • int $count - The number of comments to insert.
                                                                                      • int $comment_post_ID - The comment parent post ID.
                                                                                      • array/\\Codeception\\Module\\array/array $overrides - An associative array to override the defaults. haveManyLinksInDatabase

                                                                                        Inserts many links in the database links table.

                                                                                        // Insert 3 randomly generated links in the database.\n  $linkIds = $I->haveManyLinksInDatabase(3);\n  // Inserts links in the database replacing the `n` placeholder.\n  $linkIds = $I->haveManyLinksInDatabase(3, ['link_url' => 'http://example.org/test-{{n}}']);\n
                                                                                        Parameters
                                                                                        • int $count - The number of links to insert.
                                                                                        • array/\\Codeception\\Module\\array/array $overrides - Overrides for the default arguments. haveManyPostsInDatabase

                                                                                          Inserts many posts in the database returning their IDs. An array of values to override the defaults. The {{n}} placeholder can be used to have the post count inserted in its place; e.g. Post Title - {{n}} will be set to Post Title - 0 for the first post, Post Title - 1 for the second one and so on. The same applies to meta values as well.

                                                                                          // Insert 3 random posts.\n  $I->haveManyPostsInDatabase(3);\n  // Insert 3 posts with generated titles.\n  $I->haveManyPostsInDatabase(3, ['post_title' => 'Test post {{n}}']);\n
                                                                                          Parameters
                                                                                          • int $count - The number of posts to insert.
                                                                                          • array/\\Codeception\\Module\\array/array $overrides haveManyTermsInDatabase

                                                                                            Inserts many terms in the database.

                                                                                            $terms = $I->haveManyTermsInDatabase(3, 'genre-{{n}}', 'genre');\n  $termIds = array_column($terms, 0);\n  $termTaxonomyIds = array_column($terms, 1);\n
                                                                                            Parameters
                                                                                            • int $count - The number of terms to insert.
                                                                                            • string $name - The term name template, can include the {{n}} placeholder.
                                                                                            • string $taxonomy - The taxonomy to insert the terms for.
                                                                                            • array/\\Codeception\\Module\\array/array $overrides - An associative array of default overrides. haveManyUsersInDatabase

                                                                                              Inserts many users in the database.

                                                                                              $subscribers = $I->haveManyUsersInDatabase(5, 'user-{{n}}');\n  $editors = $I->haveManyUsersInDatabase(\n  5,\n  'user-{{n}}',\n  'editor',\n  ['user_email' => 'user-{{n}}@example.org']\n  );\n
                                                                                              Parameters
                                                                                              • int $count - The number of users to insert.
                                                                                              • string $user_login - The user login name.
                                                                                              • string $role - The user role.
                                                                                              • array/\\Codeception\\Module\\array/array $overrides - An array of values to override the default ones. haveMenuInDatabase

                                                                                                Creates and adds a menu to a theme location in the database.

                                                                                                list($termId, $termTaxId) = $I->haveMenuInDatabase('test', 'sidebar');\n
                                                                                                Parameters
                                                                                                • string $slug - The menu slug.
                                                                                                • string $location - The theme menu location the menu will be assigned to.
                                                                                                • array/\\Codeception\\Module\\array/array $overrides - An array of values to override the defaults. haveMenuItemInDatabase

                                                                                                  Adds a menu element to a menu for the current theme. post meta.

                                                                                                  $I->haveMenuInDatabase('test', 'sidebar');\n  $I->haveMenuItemInDatabase('test', 'Test one', 0);\n  $I->haveMenuItemInDatabase('test', 'Test two', 1);\n
                                                                                                  Parameters
                                                                                                  • string $menuSlug - The menu slug the item should be added to.
                                                                                                  • string $title - The menu item title.
                                                                                                  • int/null $menuOrder - An optional menu order, 1 based.
                                                                                                  • array/\\Codeception\\Module\\array/array $meta - An associative array that will be prefixed with _menu_item_ for the item haveOptionInDatabase

                                                                                                    Inserts an option in the database.

                                                                                                    $I->haveOptionInDatabase('posts_per_page', 23);\n  $I->haveOptionInDatabase('my_plugin_options', ['key_one' => 'value_one', 'key_two' => 89]);\n  If the option value is an object or an array then the value will be serialized.\n
                                                                                                    Parameters
                                                                                                    • string $option_name - The option name.
                                                                                                    • mixed $option_value - The option value; if an array or object it will be serialized.
                                                                                                    • string $autoload - Weather the option should be autoloaded by WordPress or not.
                                                                                                    havePageInDatabase

                                                                                                    Inserts a page in the database.

                                                                                                    // Creates a test page in the database with random values.\n  $randomPageId = $I->havePageInDatabase();\n  // Creates a test page in the database defining its title.\n  $testPageId = $I->havePageInDatabase(['post_title' => 'Test page']);\n
                                                                                                    Parameters
                                                                                                    • array/\\Codeception\\Module\\array/array $overrides - An array of values to override the default ones. havePostInDatabase

                                                                                                      Inserts a post in the database. values.

                                                                                                      // Insert a post with random values in the database.\n  $randomPostId = $I->havePostInDatabase();\n  // Insert a post with specific values in the database.\n  $I->havePostInDatabase([\n  'post_type' => 'book',\n  'post_title' => 'Alice in Wonderland',\n  'meta_input' => [\n  'readers_count' => 23\n  ],\n  'tax_input' => [\n  ['genre' => 'fiction']\n  ]\n  ]);\n
                                                                                                      Parameters
                                                                                                      • array/\\Codeception\\Module\\array/array $data - An associative array of post data to override default and random generated havePostThumbnailInDatabase

                                                                                                        Assigns the specified attachment ID as thumbnail (featured image) to a post.

                                                                                                        $attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));\n  $postId = $I->havePostInDatabase();\n  $I->havePostThumbnailInDatabase($postId, $attachmentId);\n
                                                                                                        Parameters
                                                                                                        • int $postId - The post ID to assign the thumbnail (featured image) to.
                                                                                                        • int $thumbnailId - The post ID of the attachment.
                                                                                                        havePostmetaInDatabase

                                                                                                        Adds one or more meta key and value couples in the database for a post.

                                                                                                        // Set the post-meta for a post.\n  $I->havePostmetaInDatabase($postId, 'karma', 23);\n  // Set an array post-meta for a post, it will be serialized in the db.\n  $I->havePostmetaInDatabase($postId, 'data', ['one', 'two']);\n  // Use a loop to insert one meta per row.\n  foreach( ['one', 'two'] as $value){\n  $I->havePostmetaInDatabase($postId, 'data', $value);\n  }\n
                                                                                                        Parameters
                                                                                                        • int $postId - The post ID.
                                                                                                        • string $meta_key - The meta key.
                                                                                                        • mixed $meta_value - The value to insert in the database, objects and arrays will be serialized.
                                                                                                        haveSiteOptionInDatabase

                                                                                                        Inserts a site option in the database. If the value is an array or an object then the value will be serialized.

                                                                                                        $fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');\n
                                                                                                        Parameters
                                                                                                        • string $key - The name of the option to insert.
                                                                                                        • mixed $value - The value to insert for the option.
                                                                                                        haveSiteTransientInDatabase

                                                                                                        Inserts a site transient in the database. If the value is an array or an object then the value will be serialized.

                                                                                                        $I->haveSiteTransientInDatabase('total_comments_count', 23);\n  // This value will be serialized.\n  $I->haveSiteTransientInDatabase('api_data', ['user' => 'luca', 'token' => '11ae3ijns-j83']);\n
                                                                                                        Parameters
                                                                                                        • string $key - The key of the site transient to insert, w/o the _site_transient_ prefix.
                                                                                                        • mixed $value - The value to insert; if serializable the value will be serialized.
                                                                                                        haveTermInDatabase

                                                                                                        Inserts a term in the database.

                                                                                                        // Insert a random 'genre' term in the database.\n  $I->haveTermInDatabase('non-fiction', 'genre');\n  // Insert a term in the database with term meta.\n  $I->haveTermInDatabase('fiction', 'genre', [\n  'slug' => 'genre--fiction',\n  'meta' => [\n  'readers_count' => 23\n  ]\n  ]);\n
                                                                                                        Parameters
                                                                                                        • string $name - The term name, e.g. \"Fuzzy\".
                                                                                                        • string $taxonomy - The term taxonomy
                                                                                                        • array/\\Codeception\\Module\\array/array $overrides - An array of values to override the default ones. haveTermMetaInDatabase

                                                                                                          Inserts a term meta row in the database. Objects and array meta values will be serialized.

                                                                                                          $I->haveTermMetaInDatabase($fictionId, 'readers_count', 23);\n  // Insert some meta that will be serialized.\n  $I->haveTermMetaInDatabase($fictionId, 'flags', [3, 4, 89]);\n  // Use a loop to insert one meta per row.\n  foreach([3, 4, 89] as $value) {\n  $I->haveTermMetaInDatabase($fictionId, 'flag', $value);\n  }\n
                                                                                                          Parameters
                                                                                                          • int $term_id - The ID of the term to insert the meta for.
                                                                                                          • string $meta_key - The key of the meta to insert.
                                                                                                          • mixed $meta_value - The value of the meta to insert, if serializable it will be serialized.
                                                                                                          haveTermRelationshipInDatabase

                                                                                                          Creates a term relationship in the database. No check about the consistency of the insertion is made. E.g. a post could be assigned a term from a taxonomy that's not registered for that post type.

                                                                                                          // Assign the `fiction` term to a book.\n  $I->haveTermRelationshipInDatabase($bookId, $fictionId);\n
                                                                                                          Parameters
                                                                                                          • int $object_id - A post ID, a user ID or anything that can be assigned a taxonomy term.
                                                                                                          • int $term_taxonomy_id - The term_taxonomy_id of the term and taxonomy to create a relation with.
                                                                                                          • int $term_order - Defaults to 0.
                                                                                                          haveTransientInDatabase

                                                                                                          Inserts a transient in the database. If the value is an array or an object then the value will be serialized. Since the transients are set in the context of tests it's not possible to set an expiration directly.

                                                                                                          // Store an array in the `tweets` transient.\n  $I->haveTransientInDatabase('tweets', $tweets);\n
                                                                                                          Parameters
                                                                                                          • string $transient - The transient name.
                                                                                                          • mixed $value - The transient value.
                                                                                                          haveUserCapabilitiesInDatabase

                                                                                                          Sets a user capabilities in the database.

                                                                                                          // Assign one user a role in a blog.\n  $blogId = $I->haveBlogInDatabase('test');\n  $editor = $I->haveUserInDatabase('luca', 'editor');\n  $capsIds = $I->haveUserCapabilitiesInDatabase($editor, [$blogId => 'editor']);\n  // Assign a user two roles in blog 1.\n  $capsIds = $I->haveUserCapabilitiesInDatabase($userId, ['editor', 'subscriber']);\n  // Assign one user different roles in different blogs.\n  $capsIds = $I->haveUserCapabilitiesInDatabase($userId, [$blogId1 => 'editor', $blogId2 => 'author']);\n  // Assign a user a role and an additional capability in blog 1.\n  $I->haveUserCapabilitiesInDatabase($userId, ['editor' => true, 'edit_themes' => true]);\n  // Assign a user a mix of roles and capabilities in different blogs.\n  $capsIds = $I->haveUserCapabilitiesInDatabase(\n  $userId,\n  [\n  $blogId1 => ['editor' => true, 'edit_themes' => true],\n  $blogId2 => ['administrator' => true, 'edit_themes' => false]\n  ]\n  );\n  associative array of blog IDs/roles for a multisite\n  installation (e.g. `[1 => 'administrator`, 2 =>\n  'subscriber']`).\n
                                                                                                          Parameters
                                                                                                          • int $userId - The ID of the user to set the capabilities of.
                                                                                                          • string/\\Codeception\\Module\\array/\\Codeception\\Module\\array $role - Either a role string (e.g. administrator),an haveUserInDatabase

                                                                                                            Inserts a user and its meta in the database. defaults to subscriber. If more than one role is specified, then the first role in the list will be the user primary role and the wp_user_level will be set to that role. in the users and usermeta table.

                                                                                                            // Create an editor user in blog 1 w/ specific email.\n  $userId = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);\n  // Create a subscriber user in blog 1.\n  $subscriberId = $I->haveUserInDatabase('subscriber');\n  // Create a user editor in blog 1, author in blog 2, administrator in blog 3.\n  $userWithMeta = $I->haveUserInDatabase('luca',\n  [\n  1 => 'editor',\n  2 => 'author',\n  3 => 'administrator'\n  ], [\n  'user_email' => 'luca@example.org'\n  'meta' => ['a meta_key' => 'a_meta_value']\n  ]\n  );\n  // Create editor in blog 1 w/ `edit_themes` cap, author in blog 2, admin in blog 3 w/o `manage_options` cap.\n  $userWithMeta = $I->haveUserInDatabase('luca',\n  [\n  1 => ['editor', 'edit_themes'],\n  2 => 'author',\n  3 => ['administrator' => true, 'manage_options' => false]\n  ]\n  );\n  // Create a user w/o role.\n  $userId = $I->haveUserInDatabase('luca', '');\n
                                                                                                            Parameters
                                                                                                            • string $user_login - The user login name.
                                                                                                            • string/string/\\Codeception\\Module\\array $role - The user role slug(s), e.g. administrator or ['author', 'editor'];
                                                                                                            • array/\\Codeception\\Module\\array/array $overrides - An associative array of column names and values overriding defaults haveUserLevelsInDatabase

                                                                                                              Sets the user access level meta in the database for a user. IDs/roles for a multisite installation (e.g. [1 => 'administrator, 2 => 'subscriber']`).

                                                                                                              $userId = $I->haveUserInDatabase('luca', 'editor');\n  $moreThanAnEditorLessThanAnAdmin = 8;\n  $I->haveUserLevelsInDatabase($userId, $moreThanAnEditorLessThanAnAdmin);\n
                                                                                                              Parameters
                                                                                                              • int $userId - The ID of the user to set the level for.
                                                                                                              • \\Codeception\\Module\\array/string $role - Either a role string (e.g. administrator) or an array of blog haveUserMetaInDatabase

                                                                                                                Sets a user meta in the database.

                                                                                                                $userId = $I->haveUserInDatabase('luca', 'editor');\n  $I->haveUserMetaInDatabase($userId, 'karma', 23);\n  values will trigger the insertion of multiple rows.\n
                                                                                                                Parameters
                                                                                                                • int $userId - The user ID.
                                                                                                                • string $meta_key - The meta key to set the value for.
                                                                                                                • mixed $meta_value - Either a single value or an array of values; objects will be serialized while array of
                                                                                                                importSql

                                                                                                                Loads a set SQL code lines in the current database.

                                                                                                                // Import a SQL string.\n  $I->importSql([$sqlString]);\n  // Import a set of SQL strings.\n  $I->importSql($sqlStrings);\n  // Import a prepared set of SQL strings.\n  $preparedSqlStrings = array_map(function($line){\n  return str_replace('{{date}}', date('Y-m-d H:i:s'), $line);\n  }, $sqlTemplate);\n  $I->importSql($preparedSqlStrings);\n
                                                                                                                Parameters
                                                                                                                • \\Codeception\\Module\\array/array $sql - The SQL strings to load. importSqlDumpFile

                                                                                                                  Import the SQL dump file if populate is enabled.

                                                                                                                  // Import a dump file passing the absolute path.\n  $I->importSqlDumpFile(codecept_data_dir('dumps/start.sql'));\n  Specifying a dump file that file will be imported.\n
                                                                                                                  Parameters
                                                                                                                  • string/null $dumpFile - The dump file that should be imported in place of the default one.
                                                                                                                  seeAttachmentInDatabase

                                                                                                                  Checks for an attachment in the database.

                                                                                                                  $url = 'https://example.org/images/foo.png';\n  $I->seeAttachmentInDatabase(['guid' => $url]);\n
                                                                                                                  Parameters
                                                                                                                  • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeBlogInDatabase

                                                                                                                    Checks for a blog in the blogs table.

                                                                                                                    // Search for a blog by `blog_id`.\n  $I->seeBlogInDatabase(['blog_id' => 23]);\n  // Search for all blogs on a path.\n  $I->seeBlogInDatabase(['path' => '/sub-path/']);\n
                                                                                                                    Parameters
                                                                                                                    • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeCommentInDatabase

                                                                                                                      Checks for a comment in the database. Will look up the \"comments\" table.

                                                                                                                      $I->seeCommentInDatabase(['comment_ID' => 23]);\n
                                                                                                                      Parameters
                                                                                                                      • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeCommentMetaInDatabase

                                                                                                                        Checks that a comment meta value is in the database. Will look up the \"commentmeta\" table.

                                                                                                                        // Assert a specified meta for a comment exists.\n  $I->seeCommentMetaInDatabase(['comment_ID' => $commentId, 'meta_key' => 'karma', 'meta_value' => 23]);\n  // Assert the comment has at least one meta set.\n  $I->seeCommentMetaInDatabase(['comment_ID' => $commentId]);\n
                                                                                                                        Parameters
                                                                                                                        • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeLinkInDatabase

                                                                                                                          Checks for a link in the links table of the database.

                                                                                                                          // Asserts a link exists by name.\n  $I->seeLinkInDatabase(['link_name' => 'my-link']);\n  // Asserts at least one link exists for the user.\n  $I->seeLinkInDatabase(['link_owner' => $userId]);\n
                                                                                                                          Parameters
                                                                                                                          • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeOptionInDatabase

                                                                                                                            Checks if an option is in the database for the current blog, either by criteria or by name and value. If checking for an array or an object then the serialized version will be checked for.

                                                                                                                            // Checks an option is in the database.\n  $I->seeOptionInDatabase('tables_version');\n  // Checks an option is in the database and has a specific value.\n  $I->seeOptionInDatabase('tables_version', '1.0');\n  $I->seeOptionInDatabase(['option_name' => 'tables_version', 'option_value' => 1.0']);\n
                                                                                                                            Parameters
                                                                                                                            • \\Codeception\\Module\\array/string $criteriaOrName - An array of search criteria or the option name.
                                                                                                                            • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                                                                                            • seePageInDatabase

                                                                                                                              Checks for a page in the database.

                                                                                                                              // Asserts a page with an exists in the database.\n  $I->seePageInDatabase(['ID' => 23]);\n  // Asserts a page with a slug and ID exists in the database.\n  $I->seePageInDatabase(['post_title' => 'Test Page', 'ID' => 23]);\n
                                                                                                                              Parameters
                                                                                                                              • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seePostInDatabase

                                                                                                                                Checks for a post in the database.

                                                                                                                                // Assert a post exists in the database.\n  $I->seePostInDatabase(['ID' => 23]);\n  // Assert a post with a slug and ID exists in the database.\n  $I->seePostInDatabase(['post_content' => 'test content', 'ID' => 23]);\n
                                                                                                                                Parameters
                                                                                                                                • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seePostMetaInDatabase

                                                                                                                                  Checks for a post meta value in the database for the current blog. If the meta_value is an object or an array then the check will be made for serialized values.

                                                                                                                                  $postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']];\n  $I->seePostMetaInDatabase(['post_id' => '$postId', 'meta_key' => 'foo']);\n
                                                                                                                                  Parameters
                                                                                                                                  • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seePostWithTermInDatabase

                                                                                                                                    Checks that a post to term relation exists in the database. The method will check the \"term_relationships\" table.

                                                                                                                                    $fiction = $I->haveTermInDatabase('fiction', 'genre');\n  $postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);\n  $I->seePostWithTermInDatabase($postId, $fiction['term_taxonomy_id']);\n  passed this parameter will be interpreted as a `term_id`, else as a\n  the\n  term order.\n  to build a `taxonomy_term_id` from the `term_id`.\n
                                                                                                                                    Parameters
                                                                                                                                    • int $post_id - The post ID.
                                                                                                                                    • int $term_taxonomy_id - The term term_id or term_taxonomy_id; if the $taxonomy argument is
                                                                                                                                    • int/null $term_order - The order the term applies to the post, defaults to null to not use
                                                                                                                                    • string/null $taxonomy - The taxonomy the term_id is for; if passed this parameter will be used
                                                                                                                                    seeSiteOptionInDatabase

                                                                                                                                    Checks that a site option is in the database.

                                                                                                                                    // Check that the option is set in the database.\n  $I->seeSiteOptionInDatabase('foo_count');\n  // Check that the option is set and has a specific value.\n  $I->seeSiteOptionInDatabase('foo_count', 23);\n
                                                                                                                                    Parameters
                                                                                                                                    • \\Codeception\\Module\\array/string $criteriaOrName - An array of search criteria or the option name.
                                                                                                                                    • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                                                                                                    • seeSiteSiteTransientInDatabase

                                                                                                                                      Checks that a site option is in the database.

                                                                                                                                      // Check a transient exists.\n  $I->seeSiteSiteTransientInDatabase('total_counts');\n  // Check a transient exists and has a specific value.\n  $I->seeSiteSiteTransientInDatabase('total_counts', 23);\n
                                                                                                                                      Parameters
                                                                                                                                      • string $key - The name of the transient to check for, w/o the _site_transient_ prefix.
                                                                                                                                      • mixed/null $value - If provided then the assertion will include the value.
                                                                                                                                      seeTableInDatabase

                                                                                                                                      Checks that a table is in the database.

                                                                                                                                      $options = $I->grabPrefixedTableNameFor('options');\n  $I->seeTableInDatabase($options);\n
                                                                                                                                      Parameters
                                                                                                                                      • string $table - The full table name, including the table prefix.
                                                                                                                                      seeTermInDatabase

                                                                                                                                      Checks for a term in the database. Looks up the terms and term_taxonomy prefixed tables. and the term_taxonomy tables.

                                                                                                                                      $I->seeTermInDatabase(['slug' => 'genre--fiction']);\n  $I->seeTermInDatabase(['name' => 'Fiction', 'slug' => 'genre--fiction']);\n
                                                                                                                                      Parameters
                                                                                                                                      • \\Codeception\\Module\\array/array $criteria - An array of criteria to search for the term, can be columns from the terms seeTermMetaInDatabase

                                                                                                                                        Checks for a term meta in the database.

                                                                                                                                        list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n  $I->haveTermMetaInDatabase($termId, 'rating', 4);\n  $I->seeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'rating', 'meta_value' => 4]);\n
                                                                                                                                        Parameters
                                                                                                                                        • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeTermRelationshipInDatabase

                                                                                                                                          Checks for a term relationship in the database.

                                                                                                                                          $postId = $I->havePostInDatabase(['tax_input' => ['category' => 'one']]);\n  $I->seeTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $oneTermTaxId]);\n
                                                                                                                                          Parameters
                                                                                                                                          • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeTermTaxonomyInDatabase

                                                                                                                                            Checks for a taxonomy taxonomy in the database.

                                                                                                                                            list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');\n  $I->seeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'genre']);\n
                                                                                                                                            Parameters
                                                                                                                                            • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeUserInDatabase

                                                                                                                                              Checks that a user is in the database. The method will check the \"users\" table.

                                                                                                                                              $I->seeUserInDatabase([\n  \"user_email\" => \"test@example.org\",\n  \"user_login\" => \"login name\"\n  ])\n
                                                                                                                                              Parameters
                                                                                                                                              • \\Codeception\\Module\\array/array $criteria - An array of search criteria. seeUserMetaInDatabase

                                                                                                                                                Checks for a user meta value in the database.

                                                                                                                                                $I->seeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);\n
                                                                                                                                                Parameters
                                                                                                                                                • \\Codeception\\Module\\array/array $criteria - An array of search criteria. useBlog

                                                                                                                                                  Sets the blog to be used. This has nothing to do with WordPress switch_to_blog function, this code will affect the table prefixes used.

                                                                                                                                                  // Switch to the blog with ID 23.\n  $I->useBlog(23);\n  // Switch back to the main blog.\n  $I->useMainBlog();\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $blogId - The ID of the blog to use.
                                                                                                                                                  useMainBlog

                                                                                                                                                  Sets the current blog to the main one (blog_id 1).

                                                                                                                                                  // Switch to the blog with ID 23.\n  $I->useBlog(23);\n  // Switch back to the main blog.\n  $I->useMainBlog();\n
                                                                                                                                                  useTheme

                                                                                                                                                  Sets the current theme options.

                                                                                                                                                  $I->useTheme('twentyseventeen');\n  $I->useTheme('child-of-twentyseventeen', 'twentyseventeen');\n  $I->useTheme('acme', 'acme', 'Acme Theme');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $stylesheet - The theme stylesheet slug, e.g. twentysixteen.
                                                                                                                                                  • string $template - The theme template slug, e.g. twentysixteen, defaults to $stylesheet.
                                                                                                                                                  • string $themeName - The theme name, e.g. Acme, defaults to the \"title\" version of

                                                                                                                                                  This class extends \\Codeception\\Module\\Db

                                                                                                                                                  This class implements \\Codeception\\Lib\\Interfaces\\Db

                                                                                                                                                  "},{"location":"v3/modules/WPFilesystem/","title":"WPFilesystem","text":"

                                                                                                                                                  This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                  "},{"location":"v3/modules/WPFilesystem/#wpfilesystem-module","title":"WPFilesystem module","text":"

                                                                                                                                                  This module should be used in acceptance and functional tests, see levels of testing for more information. This module extends the Filesystem module adding WordPress-specific configuration parameters and methods. The module provides methods to read, write and update the WordPress filesystem directly, without relying on WordPress methods, using WordPress functions or triggering WordPress filters. This module also provides methods to scaffold plugins and themes on the fly in the context of tests and auto-remove them after each test.

                                                                                                                                                  "},{"location":"v3/modules/WPFilesystem/#module-requirements-for-codeception-40","title":"Module requirements for Codeception 4.0+","text":"

                                                                                                                                                  This module requires the codeception/module-filesystem Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                  To install the package run:

                                                                                                                                                  composer require --dev codeception/module-filesystem:^1.0\n
                                                                                                                                                  "},{"location":"v3/modules/WPFilesystem/#configuration","title":"Configuration","text":"
                                                                                                                                                  • wpRootFolder required The absolute, or relative to the project root folder, path to the root WordPress installation folder. The WordPress installation root folder is the one that contains the wp-load.php file.
                                                                                                                                                  • themes - defaults to /wp-content/themes; the path, relative to the the WordPress installation root folder, to the themes folder.
                                                                                                                                                  • plugins - defaults to /wp-content/plugins; the path, relative to the WordPress installation root folder, to the plugins folder.
                                                                                                                                                  • mu-plugins - defaults to wp-content/mu-plugins; the path, relative to the WordPress installation root folder, to the must-use plugins folder.
                                                                                                                                                  • uploads - defaults to /wp-content/uploads; the path, relative to the WordPress installation root folder, to the uploads folder.
                                                                                                                                                  "},{"location":"v3/modules/WPFilesystem/#example-configuration","title":"Example configuration","text":"
                                                                                                                                                  modules:\n    enabled:\n        - WPFilesystem\n    config:\n        WPFilesystem:\n            wpRootFolder: \"/var/www/wordpress\"\n
                                                                                                                                                  "},{"location":"v3/modules/WPFilesystem/#public-api","title":"Public API","text":"
                                                                                                                                                  • amInMuPluginPath
                                                                                                                                                  • amInPluginPath
                                                                                                                                                  • amInThemePath
                                                                                                                                                  • amInUploadsPath
                                                                                                                                                  • cleanMuPluginDir
                                                                                                                                                  • cleanPluginDir
                                                                                                                                                  • cleanThemeDir
                                                                                                                                                  • cleanUploadsDir
                                                                                                                                                  • copyDirToMuPlugin
                                                                                                                                                  • copyDirToPlugin
                                                                                                                                                  • copyDirToTheme
                                                                                                                                                  • copyDirToUploads
                                                                                                                                                  • deleteMuPluginFile
                                                                                                                                                  • deletePluginFile
                                                                                                                                                  • deleteThemeFile
                                                                                                                                                  • deleteUploadedDir
                                                                                                                                                  • deleteUploadedFile
                                                                                                                                                  • dontSeeInMuPluginFile
                                                                                                                                                  • dontSeeInPluginFile
                                                                                                                                                  • dontSeeInThemeFile
                                                                                                                                                  • dontSeeInUploadedFile
                                                                                                                                                  • dontSeeMuPluginFileFound
                                                                                                                                                  • dontSeePluginFileFound
                                                                                                                                                  • dontSeeThemeFileFound
                                                                                                                                                  • dontSeeUploadedFileFound
                                                                                                                                                  • getBlogUploadsPath
                                                                                                                                                  • getUploadsPath
                                                                                                                                                  • getWpRootFolder
                                                                                                                                                  • haveMuPlugin
                                                                                                                                                  • havePlugin
                                                                                                                                                  • haveTheme
                                                                                                                                                  • makeUploadsDir
                                                                                                                                                  • openUploadedFile
                                                                                                                                                  • seeInMuPluginFile
                                                                                                                                                  • seeInPluginFile
                                                                                                                                                  • seeInThemeFile
                                                                                                                                                  • seeInUploadedFile
                                                                                                                                                  • seeMuPluginFileFound
                                                                                                                                                  • seePluginFileFound
                                                                                                                                                  • seeThemeFileFound
                                                                                                                                                  • seeUploadedFileFound
                                                                                                                                                  • writeToMuPluginFile
                                                                                                                                                  • writeToPluginFile
                                                                                                                                                  • writeToThemeFile
                                                                                                                                                  • writeToUploadedFile
                                                                                                                                                  amInMuPluginPath

                                                                                                                                                  Sets the current working folder to a folder in a mu-plugin.

                                                                                                                                                  $I->amInMuPluginPath('mu-plugin');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - The path to the folder, relative to the mu-plugins root folder.
                                                                                                                                                  amInPluginPath

                                                                                                                                                  Sets the current working folder to a folder in a plugin.

                                                                                                                                                  $I->amInPluginPath('my-plugin');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - The folder path, relative to the root uploads folder, to change to.
                                                                                                                                                  amInThemePath

                                                                                                                                                  Sets the current working folder to a folder in a theme.

                                                                                                                                                  $I->amInThemePath('my-theme');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - The path to the theme folder, relative to themes root folder.
                                                                                                                                                  amInUploadsPath

                                                                                                                                                  Enters, changing directory, to the uploads folder in the local filesystem.

                                                                                                                                                  $I->amInUploadsPath('/logs');\n  $I->seeFileFound('shop.log');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - The path, relative to the site uploads folder.
                                                                                                                                                  cleanMuPluginDir

                                                                                                                                                  Cleans, emptying it, a folder in a mu-plugin folder.

                                                                                                                                                  $I->cleanMuPluginDir('mu-plugin1/foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $dir - The path to the directory, relative to the mu-plugins root folder.
                                                                                                                                                  cleanPluginDir

                                                                                                                                                  Cleans, emptying it, a folder in a plugin folder.

                                                                                                                                                  $I->cleanPluginDir('my-plugin/foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $dir - The path to the folder, relative to the plugins root folder.
                                                                                                                                                  cleanThemeDir

                                                                                                                                                  Clears, emptying it, a folder in a theme folder.

                                                                                                                                                  $I->cleanThemeDir('my-theme/foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $dir - The path to the folder, relative to the themese root folder.
                                                                                                                                                  cleanUploadsDir

                                                                                                                                                  Clears a folder in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->cleanUploadsDir('some/folder');\n  $I->cleanUploadsDir('some/folder', 'today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $dir - The path to the directory to delete, relative to the uploads folder.
                                                                                                                                                  • string/int/[\\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                  copyDirToMuPlugin

                                                                                                                                                  Copies a folder to a folder in a mu-plugin.

                                                                                                                                                  $I->copyDirToMuPlugin(codecept_data_dir('foo'), 'mu-plugin/foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $src - The path to the source file to copy.
                                                                                                                                                  • string $pluginDst - The path to the destination folder, relative to the mu-plugins root folder.
                                                                                                                                                  copyDirToPlugin

                                                                                                                                                  Copies a folder to a folder in a plugin.

                                                                                                                                                  // Copy the 'foo' folder to the 'foo' folder in the plugin.\n  $I->copyDirToPlugin(codecept_data_dir('foo'), 'my-plugin/foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $src - The path to the source directory to copy.
                                                                                                                                                  • string $pluginDst - The destination path, relative to the plugins root folder.
                                                                                                                                                  copyDirToTheme

                                                                                                                                                  Copies a folder in a theme folder.

                                                                                                                                                  $I->copyDirToTheme(codecept_data_dir('foo'), 'my-theme');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $src - The path to the source file.
                                                                                                                                                  • string $themeDst - The path to the destination folder, relative to the themes root folder.
                                                                                                                                                  copyDirToUploads

                                                                                                                                                  Copies a folder to the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo');\n  $I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo', 'today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $src - The path to the source file, relative to the current uploads folder.
                                                                                                                                                  • string $dst - The path to the destination file, relative to the current uploads folder.
                                                                                                                                                  • string/int/[\\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                  deleteMuPluginFile

                                                                                                                                                  Deletes a file in a mu-plugin folder.

                                                                                                                                                  $I->deleteMuPluginFile('mu-plugin1/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the mu-plugins root folder.
                                                                                                                                                  deletePluginFile

                                                                                                                                                  Deletes a file in a plugin folder.

                                                                                                                                                  $I->deletePluginFile('my-plugin/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The folder path, relative to the plugins root folder.
                                                                                                                                                  deleteThemeFile

                                                                                                                                                  Deletes a file in a theme folder.

                                                                                                                                                  $I->deleteThemeFile('my-theme/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file to delete, relative to the themes root folder.
                                                                                                                                                  deleteUploadedDir

                                                                                                                                                  Deletes a dir in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->deleteUploadedDir('folder');\n  $I->deleteUploadedDir('folder', 'today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $dir - The path to the directory to delete, relative to the uploads folder.
                                                                                                                                                  • string/int/[\\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                  deleteUploadedFile

                                                                                                                                                  Deletes a file in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->deleteUploadedFile('some-file.txt');\n  $I->deleteUploadedFile('some-file.txt', 'today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                  • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                  dontSeeInMuPluginFile

                                                                                                                                                  Checks that a file in a mu-plugin folder does not contain a string.

                                                                                                                                                  $I->dontSeeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the mu-plugins root folder.
                                                                                                                                                  • string $contents - The contents to check the file for.
                                                                                                                                                  dontSeeInPluginFile

                                                                                                                                                  Checks that a file in a plugin folder does not contain a string.

                                                                                                                                                  $I->dontSeeInPluginFile('my-plugin/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                  • string $contents - The contents to check the file for.
                                                                                                                                                  dontSeeInThemeFile

                                                                                                                                                  Checks that a file in a theme folder does not contain a string.

                                                                                                                                                  $I->dontSeeInThemeFile('my-theme/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                  • string $contents - The contents to check the file for.
                                                                                                                                                  dontSeeInUploadedFile

                                                                                                                                                  Checks that a file in the uploads folder does contain a string. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->dontSeeInUploadedFile('some-file.txt', 'foo');\n  $I->dontSeeInUploadedFile('some-file.txt','foo', 'today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                  • string $contents - The not expected file contents or part of them.
                                                                                                                                                  • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                  dontSeeMuPluginFileFound

                                                                                                                                                  Checks that a file is not found in a mu-plugin folder.

                                                                                                                                                  $I->dontSeeMuPluginFileFound('mu-plugin1/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the mu-plugins folder.
                                                                                                                                                  dontSeePluginFileFound

                                                                                                                                                  Checks that a file is not found in a plugin folder.

                                                                                                                                                  $I->dontSeePluginFileFound('my-plugin/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                  dontSeeThemeFileFound

                                                                                                                                                  Checks that a file is not found in a theme folder.

                                                                                                                                                  $I->dontSeeThemeFileFound('my-theme/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                  dontSeeUploadedFileFound

                                                                                                                                                  Checks thata a file does not exist in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->dontSeeUploadedFileFound('some-file.txt');\n  $I->dontSeeUploadedFileFound('some-file.txt','today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                  • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                  getBlogUploadsPath

                                                                                                                                                  Returns the absolute path to a blog uploads folder or file.

                                                                                                                                                  $blogId = $I->haveBlogInDatabase('test');\n  $testTodayUploads = $I->getBlogUploadsPath($blogId);\n  $testLastMonthLogs = $I->getBlogUploadsPath($blogId, '/logs', '-1 month');\n  file or folder.\n  sub-folders in the year/month format; a UNIX timestamp or\n  a string supported by the `strtotime` function; defaults\n  to `now`.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $blogId - The blog ID to get the path for.
                                                                                                                                                  • string $file - The path, relatitve to the blog uploads folder, to the
                                                                                                                                                  • null/string/[\\DateTime](http://php.net/manual/en/class.datetime.php)/[\\DateTime](http://php.net/manual/en/class.datetime.php)Immutable $date - The date that should be used to build the uploads
                                                                                                                                                  getUploadsPath

                                                                                                                                                  Returns the path to the specified uploads file of folder. Not providing a value for $file and $date will return the uploads folder path.

                                                                                                                                                  $todaysPath = $I->getUploadsPath();\n  $lastWeek = $I->getUploadsPath('', '-1 week');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The file path, relative to the uploads folder.
                                                                                                                                                  • mixed $date - A string compatible with strtotime, a Unix timestamp or a Date object.
                                                                                                                                                  getWpRootFolder

                                                                                                                                                  Returns the absolute path to WordPress root folder without trailing slash.

                                                                                                                                                  $rootFolder = $I->getWpRootFolder();\n  $I->assertFileExists($rootFolder . 'wp-load.php');\n
                                                                                                                                                  haveMuPlugin

                                                                                                                                                  Creates a mu-plugin file, including plugin header, in the mu-plugins folder. The code can not contain the opening '<?php' tag.

                                                                                                                                                  $code = 'echo \"Hello world!\"';\n  $I->haveMuPlugin('foo-mu-plugin.php', $code);\n  // Load the code from a file.\n  $code = file_get_contents(codecept_data_dir('code/mu-plugin.php'));\n  $I->haveMuPlugin('foo-mu-plugin.php', $code);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $filename - The path to the file to create, relative to the plugins root folder.
                                                                                                                                                  • string $code - The content of the plugin file with or without the opening PHP tag.
                                                                                                                                                  havePlugin

                                                                                                                                                  Creates a plugin file, including plugin header, in the plugins folder. The plugin is just created and not activated; the code can not contain the opening '<?php' tag.

                                                                                                                                                  $code = 'echo \"Hello world!\"';\n  $I->havePlugin('foo/plugin.php', $code);\n  // Load the code from a file.\n  $code = file_get_contents(codecept_data_dir('code/plugin.php'));\n  $I->havePlugin('foo/plugin.php', $code);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - The path to the file to create, relative to the plugins folder.
                                                                                                                                                  • string $code - The content of the plugin file with or without the opening PHP tag.
                                                                                                                                                  haveTheme

                                                                                                                                                  Creates a theme file structure, including theme style file and index, in the themes folder. The theme is just created and not activated; the code can not contain the opening '<?php' tag.

                                                                                                                                                  $code = 'sayHi();';\n  $functionsCode  = 'function sayHi(){echo \"Hello world\";};';\n  $I->haveTheme('foo', $indexCode, $functionsCode);\n  // Load the code from a file.\n  $indexCode = file_get_contents(codecept_data_dir('code/index.php'));\n  $functionsCode = file_get_contents(codecept_data_dir('code/functions.php'));\n  $I->haveTheme('foo', $indexCode, $functionsCode);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $folder - The path to the theme to create, relative to the themes root folder.
                                                                                                                                                  • string $indexFileCode - The content of the theme index.php file with or without the opening PHP tag.
                                                                                                                                                  • string $functionsFileCode - The content of the theme functions.php file with or without the opening PHP tag.
                                                                                                                                                  makeUploadsDir

                                                                                                                                                  Creates an empty folder in the WordPress installation uploads folder.

                                                                                                                                                  $logsDir = $I->makeUploadsDir('logs/acme');\n  to create.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - The path, relative to the WordPress installation uploads folder, of the folder
                                                                                                                                                  openUploadedFile

                                                                                                                                                  Opens a file in the the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->openUploadedFile('some-file.txt');\n  $I->openUploadedFile('some-file.txt', 'time');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $filename - The path to the file, relative to the current uploads folder.
                                                                                                                                                  • string/int/[\\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                  seeInMuPluginFile

                                                                                                                                                  Checks that a file in a mu-plugin folder contains a string.

                                                                                                                                                  $I->seeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path the file, relative to the mu-plugins root folder.
                                                                                                                                                  • string $contents - The contents to check the file for.
                                                                                                                                                  seeInPluginFile

                                                                                                                                                  Checks that a file in a plugin folder contains a string.

                                                                                                                                                  $I->seeInPluginFile('my-plugin/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                  • string $contents - The contents to check the file for.
                                                                                                                                                  seeInThemeFile

                                                                                                                                                  Checks that a file in a theme folder contains a string.

                                                                                                                                                  <?php\n  $I->seeInThemeFile('my-theme/some-file.txt', 'foo');\n  ?>\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                  • string $contents - The contents to check the file for.
                                                                                                                                                  seeInUploadedFile

                                                                                                                                                  Checks that a file in the uploads folder contains a string. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->seeInUploadedFile('some-file.txt', 'foo');\n  $I->seeInUploadedFile('some-file.txt','foo', 'today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                  • string $contents - The expected file contents or part of them.
                                                                                                                                                  • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                  seeMuPluginFileFound

                                                                                                                                                  Checks that a file is found in a mu-plugin folder.

                                                                                                                                                  $I->seeMuPluginFileFound('mu-plugin1/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the mu-plugins folder.
                                                                                                                                                  seePluginFileFound

                                                                                                                                                  Checks that a file is found in a plugin folder.

                                                                                                                                                  $I->seePluginFileFound('my-plugin/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to thep plugins root folder.
                                                                                                                                                  seeThemeFileFound

                                                                                                                                                  Checks that a file is found in a theme folder.

                                                                                                                                                  $I->seeThemeFileFound('my-theme/some-file.txt');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                  seeUploadedFileFound

                                                                                                                                                  Checks if file exists in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->seeUploadedFileFound('some-file.txt');\n  $I->seeUploadedFileFound('some-file.txt','today');\n  ?>\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $filename - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                  • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                  writeToMuPluginFile

                                                                                                                                                  Writes a file in a mu-plugin folder.

                                                                                                                                                  $I->writeToMuPluginFile('mu-plugin1/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the destination file, relative to the mu-plugins root folder.
                                                                                                                                                  • string $data - The data to write to the file.
                                                                                                                                                  writeToPluginFile

                                                                                                                                                  Writes a file in a plugin folder.

                                                                                                                                                  $I->writeToPluginFile('my-plugin/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                  • string $data - The data to write in the file.
                                                                                                                                                  writeToThemeFile

                                                                                                                                                  Writes a string to a file in a theme folder.

                                                                                                                                                  $I->writeToThemeFile('my-theme/some-file.txt', 'foo');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $file - The path to the file, relative to the themese root folder.
                                                                                                                                                  • string $data - The data to write to the file.
                                                                                                                                                  writeToUploadedFile

                                                                                                                                                  Writes a string to a file in the the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                  $I->writeToUploadedFile('some-file.txt', 'foo bar');\n  $I->writeToUploadedFile('some-file.txt', 'foo bar', 'today');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $filename - The path to the destination file, relative to the current uploads folder.
                                                                                                                                                  • string $data - The data to write to the file.
                                                                                                                                                  • string/int/[\\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.

                                                                                                                                                  This class extends \\Codeception\\Module\\Filesystem

                                                                                                                                                  "},{"location":"v3/modules/WPLoader/","title":"WPLoader","text":"

                                                                                                                                                  This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                  "},{"location":"v3/modules/WPLoader/#wploader-module","title":"WPLoader module","text":"

                                                                                                                                                  This module should be used in integration tests, see levels of testing for more information, to bootstrap WordPress code in the context of the tests. Setting the loadOnly parameter to true the module can be additionally used in acceptance and functional tests to access WordPress code in the tests context. This module is a wrapper around the functionalities provided by the WordPress PHPUnit Core test suite, as such it provides the same method and facilities. The parameters provided to the module duplicate the ones used in the WordPress configuration file: the WPLoader module will not bootstrap WordPress using the wp-config.php file, it will define and use its own WordPress configuration built from the module parameters.

                                                                                                                                                  "},{"location":"v3/modules/WPLoader/#everything-happens-in-a-transaction","title":"Everything happens in a transaction","text":"

                                                                                                                                                  When used to bootstrap and install WordPress (loadOnly: false) exactly as the the WordPress PHPUnit Core test suite it is based on, this module will operate any change to the database in a transaction. This means that, in the context of integration tests, the result of any write or delete operation done during the tests will be rolled back at the end of each test method; this is done for a number of reasons like performance and tests independence. Inspection of the database during tests, e.g. stopping execution using XDebug, will not show any change in the database. Keep this in mind while trying to debug integration tests using the WPLoader module. When configured to only load WordPress (loadOnly: true) then any database operation will be committed and written to the database.

                                                                                                                                                  "},{"location":"v3/modules/WPLoader/#configuration","title":"Configuration","text":"
                                                                                                                                                  • wpRootFolder required The absolute, or relative to the project root folder, path to the root WordPress installation folder. The WordPress installation root folder is the one that contains the wp-load.php file.
                                                                                                                                                  • dbName required - The name of the database used by the WordPress installation, same as the DB_NAME constant.
                                                                                                                                                  • dbHost required - The host of the database used by the WordPress installation, same as the DB_HOST constant. If the database is accessible (as is the case on the latest version of [Local by Flywheel][http://localwp.com]) via unix socket, then the string to insert here should look like this localhost:/path/to/the/mysql.sock.
                                                                                                                                                  • dbUser required - The user of the database used by the WordPress installation, same as the DB_USER constant.
                                                                                                                                                  • dbPassword required - The password of the database used by the WordPress installation, same as DB_PASSWORD constant.
                                                                                                                                                  • loadOnly - defaults to false; whether to only load WordPress, without bootstrapping a fresh installation for tests or not. Read more in the \"Using WPLoader in acceptance and functional tests\" section. If this parameter is set to true the following parameters will not apply.
                                                                                                                                                  • isolatedInstall - defaults to true, whether to install and bootstrap the WordPress installation in a secondary PHP thread for thread safety or not. Maintained for back-compatibility purposes with wp-browser first versions: to get a replica of the bootstrap process used by WordPress Core PHPUnit tests leave this to true.
                                                                                                                                                  • installationTableHandling - defaults to empty; it controls how tables created by WordPress and plugins will be handled during the installation of WordPress during tests. By default tables will be emptied of any content, but some plugins might require tables to be dropped before WordPress is installed and after plugins are activated (this used to be the default behavior). Supported values are drop to drop the tables, empty to just empty the tables and let to do nothing about the tables. If you get errors from database queries while the WPLoader module installs the tests, then try changing this parameter value.
                                                                                                                                                  • wpDebug - defaults to true, the value the WP_DEBUG constant will be set to.
                                                                                                                                                  • multisite - defaults to false, the value the MULTISITE constant will be set to.
                                                                                                                                                  • skipPluggables - defaults to false, if set to true will skip the definition of pluggable functions.
                                                                                                                                                  • dbCharset - defaults to utf8, the value the DB_CHARSET constant will be set to.
                                                                                                                                                  • dbCollate - defaults to an empty string, the value the DB_COLLATE constant will be set to.
                                                                                                                                                  • tablePrefix - defaults to wptests_, the value the $table_prefix variable will be set to.
                                                                                                                                                  • domain - defaults to example.org, the domain of the WordPress site to scaffold for the tests.
                                                                                                                                                  • adminEmail - defaults to admin@example.org, the email of the WordPress site to scaffold for the tests.
                                                                                                                                                  • title - defaults to Test Blog, the title of the WordPress site to scaffolded for the tests.
                                                                                                                                                  • phpBinary - defaults to php, the PHP binary the host machine will have to use to bootstrap and load the test WordPress installation.
                                                                                                                                                  • language - defaults to an empty string, the language of the WordPress installation to scaffold.
                                                                                                                                                  • configFile - defaults to an empty string, an additional configuration file to include before loading WordPress. Any instruction in this fill will run before any WordPress file is included.
                                                                                                                                                  • contentFolder - defaults to an empty string; the path, relative to the wpRootFolder or absolute, to the content folder if different from the default one or the one defined by the WP_CONTENT_DIR constant; if the WP_CONTENT_DIR constant is defined in a config file (see the configFile parameter) this will be ignored.
                                                                                                                                                  • pluginsFolder - defaults to an empty string; the path, relative to the wpRootFolder or absolute, to the plugins folder from the wpRootFolder if different from the default one or the one defined by the WP_PLUGIN_DIR constant; if the WP_PLUGIN_DIR constant is defined in a config file (see the configFile parameter) this will be ignored.
                                                                                                                                                  • plugins - defaults to an empty array; a list of plugins that should be loaded before any test case runs and after mu-plugins have been loaded; these should be defined in the folder/plugin-file.php format.
                                                                                                                                                  • activateplugins - defaults to an empty array, a list of plugins that will be activated before any test case runs and after wordpress is fully loaded and set up; these should be defined in the folder/plugin-file.php format; when the multisite option is set to true the plugins will be network activated during the installation.
                                                                                                                                                  • activatePluginsSilently - defaults to an empty array, a list of plugins that will be silently activated, thus not firing the plugins' activation actions, before any test case runs and after wordpress is fully loaded and set up; these should be defined in the folder/plugin-file.php format; when the multisite option is set to true the plugins will be network activated during the installation.
                                                                                                                                                  • bootstrapActions - defaults to an empty string, a list of actions, static functions or functions that should be called after before any test case runs, after plugins have been loaded and activated; static functions should be defined in the YAML array format:
                                                                                                                                                    bootstrapActions:\n    - action_one\n    - action_two\n    - [MyClass, myStaticMethod]\n    - my_function\n
                                                                                                                                                  • theme - defaults to an empty string, the theme that should be activated for the tests; if a string is passed then both template and stylesheet options will be set to the passed value; if an array is passed then the template and stylesheet will be set in that order:

                                                                                                                                                    theme: my-theme\n

                                                                                                                                                    The theme will be set to my-theme.

                                                                                                                                                    theme: [ parent, child ]\n

                                                                                                                                                    The template will be set to parent, the stylesheet will be set to child.

                                                                                                                                                  A word of caution: right now the only way to write tests able to take advantage of the suite is to use the WP_UnitTestCase test case class; while the module will load fine and will raise no problems WP_UnitTestCase will take care of handling the database as intended and using another test case class will almost certainly result in an error if the test case defines more than one test method.

                                                                                                                                                  "},{"location":"v3/modules/WPLoader/#example-configuration","title":"Example configuration","text":"
                                                                                                                                                    modules:\n      enabled:\n          - WPLoader\n      config:\n          WPLoader:\n              multisite: false\n              wpRootFolder: \"/Users/luca/www/wordpress\"\n              dbName: \"wordpress_tests\"\n              dbHost: \"localhost\"\n              dbUser: \"root\"\n              dbPassword: \"password\"\n              isolatedInstall: true\n              installationTableHandling: drop\n              tablePrefix: \"wptests_\"\n              domain: \"wordrpess.localhost\"\n              adminEmail: \"admin@wordpress.localhost\"\n              title: \"Test Blog\"\n              theme: my-theme\n              plugins: ['hello.php', 'my-plugin/my-plugin.php']\n              activatePlugins: ['hello.php', 'my-plugin/my-plugin.php']\n
                                                                                                                                                  "},{"location":"v3/modules/WPLoader/#usage-in-integration-or-wordpress-unit-tests","title":"Usage in integration or \"WordPress unit\" tests","text":"

                                                                                                                                                  The most common use of this module is to run integration, or \"WordPress unit\" tests (see levels of testing for more information).

                                                                                                                                                  As a first step generate a WPTestCase using Codeception command-line utility (see the commands provided by wp-browser):

                                                                                                                                                  codecept generate:wpunit my_suite \"Acme\\User\"\n

                                                                                                                                                  Codeception will generate the tests/my_suite/Acme/UserTest.php class. The class extends the Codeception\\TestCase\\WPTestCase class provided by wp-browser; this looks like a normal PHPUnit test case but has some perks due to it's mixed breed nature. Understanding them might help you work with it:

                                                                                                                                                  • WordPress is installed and configured for the tests before the test case is loaded; WordPress defined functions and classes (and those of the plugins and themes loaded with it) will be available in the setUpBeforeClass method.
                                                                                                                                                  • WordPress is not loaded when PHPUnit will call the data provider methods; this means the post_provider method will generate a function not found exception when the test case runs as the WordPress defined methods are not loaded yet:
                                                                                                                                                    public function post_provider(){\n        // `wp_insert_post` is loaded with WordPress and WordPress has not been loaded yet!\n        return [\n                [wp_insert_post(['post_title' => 'Test', 'post_status' => 'publish'])]\n        ];\n}\n\npublic function test_posts($post_id){\n        $this->assertInstanceOf(WP_Post::class, get_post($post_id));\n}\n
                                                                                                                                                  • WordPress is reset to an initial known state before each test runs; the database transaction is rolled back to wipe any data and tables you might have manipulated in the tests, the global space is cleaned. See Everything happens in a transaction.
                                                                                                                                                  • This is a Codeception Unit test, as such it does provide access to the $this->tester property to access the methods defined in other modules loaded in the suite and to Codeception test doubles
                                                                                                                                                  • This is a PhpUnit test case too; there are way too many testing functions to cover to report them here but, to highlight a few: mocking with Prophecy and the wealth of PHPUnit assertion methods.
                                                                                                                                                  • This is kind of a WordPress Core suite test case; as such it provides access to its functions and to the often-overlooked static::factory() method; in this instance too there are too many methods to list them all but it's worth noting how easy it is to set up test fixtures with the factory:
                                                                                                                                                    public function test_post_creation(){\n        $random_post_id = static::factory()->post->create();\n\n        $this->assertInstanceOf(WP_Post::class, get_post($random_post_id));\n}\n
                                                                                                                                                  • The factory property can be accessed on the tester property too and will work the same way as if called using static::factory():
                                                                                                                                                    public function test_post_creation(){\n        $random_post_id = $this->tester->factory()->post->create();\n\n        $this->assertInstanceOf(WP_Post::class, get_post($random_post_id));\n}\n
                                                                                                                                                  "},{"location":"v3/modules/WPLoader/#wploader-to-only-bootstrap-wordpress","title":"WPLoader to only bootstrap WordPress","text":"

                                                                                                                                                  If the need is to just bootstrap the WordPress installation in the context of the tests variable scope then the WPLoader module loadOnly parameter should be set to true; this could be the case for functional tests in need to access WordPress provided methods, functions and values. An example configuration for the module in this mode is this one:

                                                                                                                                                    modules:\n      enabled:\n          - WPDb # BEFORE the WPLoader one!\n          - WPLoader # AFTER the WPDb one!\n      config:\n          WPDb:\n              dsn: 'mysql:host=localhost;dbname=wordpress'\n              user: 'root'\n              password: 'password'\n              dump: 'tests/_data/dump.sql'\n              populate: true\n              cleanup: true\n              waitlock: 10\n              url: 'http://wordpress.localhost'\n              urlReplacement: true\n              tablePrefix: 'wp_'\n          WPLoader:\n              loadOnly: true \n              wpRootFolder: \"/Users/User/www/wordpress\"\n              dbName: \"wpress-tests\"\n              dbHost: \"localhost\"\n              dbUser: \"root\"\n              dbPassword: \"root\"\n              domain: \"wordpress.localhost\"\n

                                                                                                                                                  With reference to the table above the module will not take care of the test WordPress installation state before and after the tests, the installed and activated plugins, and theme. The module can be used in conjunction with a WPDb module to provide the tests with a WordPress installation suiting the tests at hand; when doing so please take care to list, in the suite configuration file modules section (see example above) the WPDb module before the WPLoader one. Codeception will initialize the modules in the same order they are listed in the modules section of the suite configuration file and the WPLoader module needs the database to be populated by the WPDb module before it runs! As an example this is a correct suite configuration:

                                                                                                                                                  modules:\n  enabled:\n      - WPDb # this before...\n      - WPLoader # ...this one.\n  config:\n      WPDb:\n        # ...\n      WPLoader:\n        loadOnly: true\n        # ... \n

                                                                                                                                                  "},{"location":"v3/modules/WPLoader/#public-api","title":"Public API","text":"
                                                                                                                                                  • debugWpActionFinal
                                                                                                                                                  • debugWpActionInitial
                                                                                                                                                  • debugWpFilterFinal
                                                                                                                                                  • debugWpFilterInitial
                                                                                                                                                  • factory
                                                                                                                                                  • getContentFolder
                                                                                                                                                  • getPluginsFolder
                                                                                                                                                  • startWpFiltersDebug
                                                                                                                                                  • stopWpFiltersDebug
                                                                                                                                                  debugWpActionFinal

                                                                                                                                                  Debugs a single WordPress action final call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                  // Start debugging all WordPress actions final value.\n  add_action('all', [$this,'debugWpActionFinal']);\n  // Run some code firing actions and debug them.\n  // Stop debugging all WordPress actions final value.\n  remove_action('all', [$this,'debugWpActionFinal']);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • mixed $args
                                                                                                                                                  debugWpActionInitial

                                                                                                                                                  Debugs a single WordPress action initial call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                  // Start debugging all WordPress actions initial value.\n  add_action('all', [$this,'debugWpActionInitial']);\n  // Run some code firing actions and debug them.\n  // Stop debugging all WordPress actions initial value.\n  remove_action('all', [$this,'debugWpActionInitial']);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • mixed $args
                                                                                                                                                  debugWpFilterFinal

                                                                                                                                                  Debugs a single WordPress filter final call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                  // Start debugging all WordPress filters final value.\n  add_filter('all', [$this,'debugWpFilterFinal']);\n  // Run some code firing filters and debug them.\n  // Stop debugging all WordPress filters final value.\n  remove_filter('all', [$this,'debugWpFilterFinal']);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • mixed $args
                                                                                                                                                  debugWpFilterInitial

                                                                                                                                                  Debugs a single WordPress filter initial call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                  // Start debugging all WordPress filters initial value.\n  add_filter('all', [$this,'debugWpFilterInitial']);\n  // Run some code firing filters and debug them.\n  // Stop debugging all WordPress filters initial value.\n  remove_filter('all', [$this,'debugWpFilterInitial']);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • mixed $args
                                                                                                                                                  factory

                                                                                                                                                  Accessor method to get the object storing the factories for things. This methods gives access to the same factories provided by the Core test suite.

                                                                                                                                                  $postId = $I->factory()->post->create();\n  $userId = $I->factory()->user->create(['role' => 'administrator']);\n
                                                                                                                                                  getContentFolder

                                                                                                                                                  Returns the absolute path to the WordPress content directory.

                                                                                                                                                  $content = $this->getContentFolder();\n  $themes = $this->getContentFolder('themes');\n  $twentytwenty = $this->getContentFolder('themes/twentytwenty');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - An optional path to append to the content directory absolute path.
                                                                                                                                                  getPluginsFolder

                                                                                                                                                  Returns the absolute path to the plugins directory. The value will first look at the WP_PLUGIN_DIR constant, then the pluginsFolder configuration parameter and will, finally, look in the default path from the WordPress root directory.

                                                                                                                                                  $plugins = $this->getPluginsFolder();\n  $hello = $this->getPluginsFolder('hello.php');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $path - A relative path to append to te plugins directory absolute path.
                                                                                                                                                  startWpFiltersDebug

                                                                                                                                                  Starts the debug of all WordPress filters and actions. The method hook on all filters and actions to debug their value.

                                                                                                                                                  // Start debugging all WordPress filters and action final and initial values.\n  $this->startWpFiltersDebug();\n  // Run some code firing filters and debug them.\n  // Stop debugging all WordPress filters and action final and initial values.\n  $this->stopWpFiltersDebug();\n  the array of arguments as input.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • \\callable $format - A callback function to format the arguments debug output; the callback will receive
                                                                                                                                                  stopWpFiltersDebug

                                                                                                                                                  Stops the debug of all WordPress filters and actions.

                                                                                                                                                  // Start debugging all WordPress filters and action final and initial values.\n  $this->startWpFiltersDebug();\n  // Run some code firing filters and debug them.\n  // Stop debugging all WordPress filters and action final and initial values.\n  $this->stopWpFiltersDebug();\n

                                                                                                                                                  This class extends \\Codeception\\Module

                                                                                                                                                  "},{"location":"v3/modules/WPQueries/","title":"WPQueries","text":"

                                                                                                                                                  This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                  "},{"location":"v3/modules/WPQueries/#wpqueries-module","title":"WPQueries module","text":"

                                                                                                                                                  This module should be used in integration tests, see levels of testing for more information, to make assertions on the database queries made by the global $wpdb object. This module requires the WPLoader module to work. The module will set, if not set already, the SAVEQUERIES constant to true and will throw an exception if the constant is already set to a falsy value.

                                                                                                                                                  "},{"location":"v3/modules/WPQueries/#configuration","title":"Configuration","text":"

                                                                                                                                                  This module does not require any configuration, but requires the WPLoader module to work correctly.

                                                                                                                                                  "},{"location":"v3/modules/WPQueries/#usage","title":"Usage","text":"

                                                                                                                                                  This module must be used in a test case extending the \\Codeception\\TestCase\\WPTestCase class.

                                                                                                                                                  The module public API is accessible calling via the \\Codeception\\TestCase\\WPTestCase::queries() method:

                                                                                                                                                  <?php\n\nuse Codeception\\Module\\WPQueries;\n\nclass WPQueriesUsageTest extends \\Codeception\\TestCase\\WPTestCase\n{\n    public function test_queries_made_by_factory_are_not_tracked()\n    {\n        $currentQueriesCount = $this->queries()->countQueries();\n\n        $this->assertNotEmpty($currentQueriesCount);\n\n        static::factory()->post->create_many(3);\n\n        $this->assertNotEmpty($currentQueriesCount);\n        $this->assertEquals($currentQueriesCount, $this->queries()->countQueries());\n    }\n\n    public function test_count_queries()\n    {\n        $currentQueriesCount = $this->queries()->countQueries();\n\n        $this->assertNotEmpty($currentQueriesCount);\n\n        foreach (range(1, 3) as $i) {\n            wp_insert_post(['post_title' => 'Post ' . $i, 'post_content' => str_repeat('test', $i)]);\n        }\n\n        $this->assertNotEmpty($currentQueriesCount);\n        $this->assertGreaterThan($currentQueriesCount, $this->queries()->countQueries());\n    }\n}\n
                                                                                                                                                  "},{"location":"v3/modules/WPQueries/#public-api","title":"Public API","text":"
                                                                                                                                                  • assertCountQueries
                                                                                                                                                  • assertNotQueries
                                                                                                                                                  • assertNotQueriesByAction
                                                                                                                                                  • assertNotQueriesByFilter
                                                                                                                                                  • assertNotQueriesByFunction
                                                                                                                                                  • assertNotQueriesByMethod
                                                                                                                                                  • assertNotQueriesByStatement
                                                                                                                                                  • assertNotQueriesByStatementAndAction
                                                                                                                                                  • assertNotQueriesByStatementAndFilter
                                                                                                                                                  • assertNotQueriesByStatementAndFunction
                                                                                                                                                  • assertNotQueriesByStatementAndMethod
                                                                                                                                                  • assertQueries
                                                                                                                                                  • assertQueriesByAction
                                                                                                                                                  • assertQueriesByFilter
                                                                                                                                                  • assertQueriesByFunction
                                                                                                                                                  • assertQueriesByMethod
                                                                                                                                                  • assertQueriesByStatement
                                                                                                                                                  • assertQueriesByStatementAndAction
                                                                                                                                                  • assertQueriesByStatementAndFilter
                                                                                                                                                  • assertQueriesByStatementAndFunction
                                                                                                                                                  • assertQueriesByStatementAndMethod
                                                                                                                                                  • assertQueriesCountByAction
                                                                                                                                                  • assertQueriesCountByFilter
                                                                                                                                                  • assertQueriesCountByFunction
                                                                                                                                                  • assertQueriesCountByMethod
                                                                                                                                                  • assertQueriesCountByStatement
                                                                                                                                                  • assertQueriesCountByStatementAndAction
                                                                                                                                                  • assertQueriesCountByStatementAndFilter
                                                                                                                                                  • assertQueriesCountByStatementAndFunction
                                                                                                                                                  • assertQueriesCountByStatementAndMethod
                                                                                                                                                  • countQueries
                                                                                                                                                  • getQueries
                                                                                                                                                  assertCountQueries

                                                                                                                                                  Asserts that n queries have been made.

                                                                                                                                                  $posts = $this->factory()->post->create_many(3);\n  $cachedUsers = $this->factory()->user->create_many(2);\n  $nonCachedUsers = $this->factory()->user->create_many(2);\n  foreach($cachedUsers as $userId){\n  wp_cache_set('page-posts-for-user-' . $userId, $posts, 'acme');\n  }\n  // Run the same query as different users\n  foreach(array_merge($cachedUsers, $nonCachedUsers) as $userId){\n  $pagePosts = $plugin->getPagePostsForUser($userId);\n  }\n  $I->assertCountQueries(2, 'A query should be made for each user missing cached posts.')\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueries

                                                                                                                                                  Asserts that no queries were made. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $posts = $this->factory()->post->create_many(3);\n  wp_cache_set('page-posts', $posts, 'acme');\n  $pagePosts = $plugin->getPagePosts();\n  $I->assertNotQueries('Queries should not be made if the cache is set.')\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByAction

                                                                                                                                                  Asserts that no queries were made as a consequence of the specified action. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_action( 'edit_post', function($postId){\n  $count = get_option('acme_title_updates_count');\n  update_option('acme_title_updates_count', ++$count);\n  } );\n  wp_delete_post($bookId);\n  $this->assertNotQueriesByAction('edit_post');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $action - The action name, e.g. 'init'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByFilter

                                                                                                                                                  Asserts that no queries were made as a consequence of the specified filter. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_filter('the_title', function($title, $postId){\n  $post = get_post($postId);\n  if($post->post_type !== 'book'){\n  return $title;\n  }\n  $new = get_option('acme_new_prefix');\n  return \"{$new} - \" . $title;\n  });\n  $title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);\n  $this->assertNotQueriesByFilter('the_title');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByFunction

                                                                                                                                                  Asserts that no queries were made by the specified function. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $this->assertEmpty(Acme\\get_orphaned_posts());\n  Acme\\delete_orphaned_posts();\n  $this->assertNotQueriesByFunction('Acme\\delete_orphaned_posts');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $function - The fully qualified name of the function to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByMethod

                                                                                                                                                  Asserts that no queries have been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $options = new Acme\\Options();\n  $options->update('adsSource', 'not-a-real-url.org');\n  $I->assertNotQueriesByMethod('Acme\\Options', 'update');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $class - The fully qualified name of the class to check.
                                                                                                                                                  • string $method - The name of the method to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByStatement

                                                                                                                                                  Asserts that no queries have been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $bookRepository = new Acme\\BookRepository();\n  $repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);\n  $this->assertNotQueriesByStatement('INSERT', 'Deferred write should happen on __destruct');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByStatementAndAction

                                                                                                                                                  Asserts that no queries were made as a consequence of the specified action containing the SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_action( 'edit_post', function($postId){\n  $count = get_option('acme_title_updates_count');\n  update_option('acme_title_updates_count', ++$count);\n  } );\n  wp_delete_post($bookId);\n  $this->assertNotQueriesByStatementAndAction('DELETE', 'delete_post');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $action - The action name, e.g. 'init'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByStatementAndFilter

                                                                                                                                                  Asserts that no queries were made as a consequence of the specified filter containing the specified SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_filter('the_title', function($title, $postId){\n  $post = get_post($postId);\n  if($post->post_type !== 'book'){\n  return $title;\n  }\n  $new = get_option('acme_new_prefix');\n  return \"{$new} - \" . $title;\n  });\n  $title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);\n  $this->assertNotQueriesByStatementAndFilter('SELECT', 'the_title');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByStatementAndFunction

                                                                                                                                                  Asserts that no queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  wp_insert_post(['ID' => $bookId, 'post_title' => 'The Call of the Wild']);\n  $this->assertNotQueriesByStatementAndFunction('INSERT', 'wp_insert_post');\n  $this->assertQueriesByStatementAndFunction('UPDATE', 'wp_insert_post');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $function - The name of the function to check the assertions for.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertNotQueriesByStatementAndMethod

                                                                                                                                                  Asserts that no queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  Acme\\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();\n  $this->assertQueriesByStatementAndMethod('INSERT', Acme\\BookRepository::class, 'commit');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $class - The fully qualified name of the class to check.
                                                                                                                                                  • string $method - The name of the method to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueries

                                                                                                                                                  Asserts that at least one query was made during the test. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  wp_cache_delete('page-posts', 'acme');\n  $pagePosts = $plugin->getPagePosts();\n  $I->assertQueries('Queries should be made to set the cache.')\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByAction

                                                                                                                                                  Asserts that at least one query was made as a consequence of the specified action. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_action( 'edit_post', function($postId){\n  $count = get_option('acme_title_updates_count');\n  update_option('acme_title_updates_count', ++$count);\n  } );\n  wp_update_post(['ID' => $bookId, 'post_title' => 'New Title']);\n  $this->assertQueriesByAction('edit_post');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $action - The action name, e.g. 'init'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByFilter

                                                                                                                                                  Asserts that at least one query was made as a consequence of the specified filter. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_filter('the_title', function($title, $postId){\n  $post = get_post($postId);\n  if($post->post_type !== 'book'){\n  return $title;\n  }\n  $new = get_option('acme_new_prefix');\n  return \"{$new} - \" . $title;\n  });\n  $title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);\n  $this->assertQueriesByFilter('the_title');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByFunction

                                                                                                                                                  Asserts that queries were made by the specified function. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  acme_clean_queue();\n  $this->assertQueriesByFunction('acme_clean_queue');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $function - The fully qualified name of the function to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByMethod

                                                                                                                                                  Asserts that at least one query has been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $options = new Acme\\Options();\n  $options->update('showAds', false);\n  $I->assertQueriesByMethod('Acme\\Options', 'update');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $class - The fully qualified name of the class to check.
                                                                                                                                                  • string $method - The name of the method to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByStatement

                                                                                                                                                  Asserts that at least a query starting with the specified statement was made. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  wp_cache_flush();\n  cached_get_posts($args);\n  $I->assertQueriesByStatement('SELECT');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByStatementAndAction

                                                                                                                                                  Asserts that at least one query was made as a consequence of the specified action containing the SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_action( 'edit_post', function($postId){\n  $count = get_option('acme_title_updates_count');\n  update_option('acme_title_updates_count', ++$count);\n  } );\n  wp_update_post(['ID' => $bookId, 'post_title' => 'New']);\n  $this->assertQueriesByStatementAndAction('UPDATE', 'edit_post');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $action - The action name, e.g. 'init'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByStatementAndFilter

                                                                                                                                                  Asserts that at least one query was made as a consequence of the specified filter containing the SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_filter('the_title', function($title, $postId){\n  $post = get_post($postId);\n  if($post->post_type !== 'book'){\n  return $title;\n  }\n  $new = get_option('acme_new_prefix');\n  return \"{$new} - \" . $title;\n  });\n  $title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);\n  $this->assertQueriesByStatementAndFilter('SELECT', 'the_title');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByStatementAndFunction

                                                                                                                                                  Asserts that queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);\n  $this->assertQueriesByStatementAndFunction('INSERT', 'wp_insert_post');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $function - The fully qualified function name.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesByStatementAndMethod

                                                                                                                                                  Asserts that queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  Acme\\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();\n  $this->assertQueriesByStatementAndMethod('UPDATE', Acme\\BookRepository::class, 'commit');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $class - The fully qualified name of the class to check.
                                                                                                                                                  • string $method - The name of the method to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByAction

                                                                                                                                                  Asserts that n queries were made as a consequence of the specified action. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_action( 'edit_post', function($postId){\n  $count = get_option('acme_title_updates_count');\n  update_option('acme_title_updates_count', ++$count);\n  } );\n  wp_update_post(['ID' => $bookOneId, 'post_title' => 'One']);\n  wp_update_post(['ID' => $bookTwoId, 'post_title' => 'Two']);\n  wp_update_post(['ID' => $bookThreeId, 'post_title' => 'Three']);\n  $this->assertQueriesCountByAction(3, 'edit_post');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $action - The action name, e.g. 'init'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByFilter

                                                                                                                                                  Asserts that n queries were made as a consequence of the specified filter. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_filter('the_title', function($title, $postId){\n  $post = get_post($postId);\n  if($post->post_type !== 'book'){\n  return $title;\n  }\n  $new = get_option('acme_new_prefix');\n  return \"{$new} - \" . $title;\n  });\n  $title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);\n  $title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);\n  $title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);\n  $this->assertQueriesCountByFilter(2, 'the_title');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByFunction

                                                                                                                                                  Asserts that n queries were made by the specified function. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $this->assertCount(3, Acme\\get_orphaned_posts());\n  Acme\\delete_orphaned_posts();\n  $this->assertQueriesCountByFunction(3, 'Acme\\delete_orphaned_posts');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $function - The function to check the queries for.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByMethod

                                                                                                                                                  Asserts that n queries have been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $bookRepository = new Acme\\BookRepository();\n  $repository->where('ID', 23)->commit('title', 'Peter Pan');\n  $repository->where('ID', 89)->commit('title', 'Moby-dick');\n  $repository->where('ID', 2389)->commit('title', 'The call of the wild');\n  $this->assertQueriesCountByMethod(3, 'Acme\\BookRepository', 'commit');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $class - The fully qualified name of the class to check.
                                                                                                                                                  • string $method - The name of the method to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByStatement

                                                                                                                                                  Asserts that n queries starting with the specified statement were made. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  $bookRepository = new Acme\\BookRepository();\n  $repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);\n  $repository->where('ID', 89)->set('title', 'Moby-dick', $deferred = true);\n  $repository->where('ID', 2389)->set('title', 'The call of the wild', $deferred = false);\n  $this->assertQueriesCountByStatement(1, 'INSERT', 'Deferred write should happen on __destruct');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByStatementAndAction

                                                                                                                                                  Asserts that n queries were made as a consequence of the specified action containing the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_action( 'edit_post', function($postId){\n  $count = get_option('acme_title_updates_count');\n  update_option('acme_title_updates_count', ++$count);\n  } );\n  wp_delete_post($bookOneId);\n  wp_delete_post($bookTwoId);\n  wp_update_post(['ID' => $bookThreeId, 'post_title' => 'New']);\n  $this->assertQueriesCountByStatementAndAction(2, 'DELETE', 'delete_post');\n  $this->assertQueriesCountByStatementAndAction(1, 'INSERT', 'edit_post');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $action - The action name, e.g. 'init'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByStatementAndFilter

                                                                                                                                                  Asserts that n queries were made as a consequence of the specified filter containing the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  add_filter('the_title', function($title, $postId){\n  $post = get_post($postId);\n  if($post->post_type !== 'book'){\n  return $title;\n  }\n  $new = get_option('acme_new_prefix');\n  return \"{$new} - \" . $title;\n  });\n  // Warm up the cache.\n  $title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);\n  // Cache is warmed up now.\n  $title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);\n  $title = apply_filters('the_title', get_post($bookThreeId)->post_title, $bookThreeId);\n  $this->assertQueriesCountByStatementAndFilter(1, 'SELECT', 'the_title');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByStatementAndFunction

                                                                                                                                                  Asserts that n queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  wp_insert_post(['post_type' => 'book', 'post_title' => 'The Call of the Wild']);\n  wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);\n  wp_insert_post(['post_type' => 'book', 'post_title' => 'The Chocolate Factory']);\n  $this->assertQueriesCountByStatementAndFunction(3, 'INSERT', 'wp_insert_post');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $function - The fully-qualified function name.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  assertQueriesCountByStatementAndMethod

                                                                                                                                                  Asserts that n queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                  Acme\\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();\n  Acme\\BookRepository::new(['title' => 'Moby-Dick'])->commit();\n  Acme\\BookRepository::new(['title' => 'The Call of the Wild'])->commit();\n  $this->assertQueriesCountByStatementAndMethod(3, 'INSERT', Acme\\BookRepository::class, 'commit');\n  Regular expressions must contain delimiters.\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $n - The expected number of queries.
                                                                                                                                                  • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                  • string $class - The fully qualified name of the class to check.
                                                                                                                                                  • string $method - The name of the method to check.
                                                                                                                                                  • string $message - An optional message to override the default one.
                                                                                                                                                  countQueries

                                                                                                                                                  Returns the current number of queries. Set-up and tear-down queries performed by the test case are filtered out.

                                                                                                                                                  // In a WPTestCase, using the global $wpdb object.\n  $queriesCount = $this->queries()->countQueries();\n  // In a WPTestCase, using a custom $wpdb object.\n  $queriesCount = $this->queries()->countQueries($customWdbb);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • \\wpdb/null $wpdb - A specific instance of the wpdb class or null to use the global one.
                                                                                                                                                  getQueries

                                                                                                                                                  Returns the queries currently performed by the global database object or the specified one. Set-up and tear-down queries performed by the test case are filtered out.

                                                                                                                                                  // In a WPTestCase, using the global $wpdb object.\n  $queries = $this->queries()->getQueries();\n  // In a WPTestCase, using a custom $wpdb object.\n  $queries = $this->queries()->getQueries($customWdbb);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • null/\\wpdb $wpdb - A specific instance of the wpdb class or null to use the global one.

                                                                                                                                                  This class extends \\Codeception\\Module

                                                                                                                                                  "},{"location":"v3/modules/WPWebDriver/","title":"WPWebDriver","text":"

                                                                                                                                                  This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                  "},{"location":"v3/modules/WPWebDriver/#wpwebdriver-module","title":"WpWebDriver module","text":"

                                                                                                                                                  This module should be used in acceptance tests, see levels of testing for more information.

                                                                                                                                                  This module extends the WebDriver module adding WordPress-specific configuration parameters and methods.

                                                                                                                                                  The module simulates a user interaction with the site with Javascript support; if you don't need to test your project with Javascript support use the WPBrowser module.

                                                                                                                                                  "},{"location":"v3/modules/WPWebDriver/#module-requirements-for-codeception-40","title":"Module requirements for Codeception 4.0+","text":"

                                                                                                                                                  This module requires the codeception/module-webdriver Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                  To install the package run:

                                                                                                                                                  composer require --dev codeception/module-webdriver:^1.0\n
                                                                                                                                                  "},{"location":"v3/modules/WPWebDriver/#configuration","title":"Configuration","text":"

                                                                                                                                                  Due to the combination of possible browsers, capabilities and configurations, it's not possible to provide an exhaustive coverage of all the possible configuration parameteters here.

                                                                                                                                                  Please refer to WebDriver documentation for more information.

                                                                                                                                                  • url required - Start URL of your WordPress project, e.g. http://wp.test.
                                                                                                                                                  • adminUsername required - This is the login name, not the \"nice\" name, of the administrator user of the WordPress test site. This will be used to fill the username field in WordPress login page.
                                                                                                                                                  • adminPassword required - This is the the password of the administrator use of the WordPress test site. This will be used to fill the password in WordPress login page.
                                                                                                                                                  • adminPath required - The path, relative to the WordPress test site home URL, to the administration area, usually /wp-admin.
                                                                                                                                                  • browser - The browser to use for the tests, e.g. chrome or firefox.
                                                                                                                                                  • capabilities - Depending on the browser set in browser this is a list of browser-specific capabilities.
                                                                                                                                                  "},{"location":"v3/modules/WPWebDriver/#example-configuration","title":"Example configuration","text":"
                                                                                                                                                  modules:\n  enabled:\n    - WPWebDriver\n  config:\n    WPWebDriver:\n      url: 'http://wp.test'\n      adminUsername: 'admin'\n      adminPassword: 'password'\n      adminPath: '/wp-admin'\n      browser: chrome\n      host: localhost\n      port: 4444\n      window_size: false #disabled for Chrome driver\n      capabilities:\n        \"goog:chromeOptions\":\n          args:\n            - \"--headless\"\n            - \"--disable-gpu\"\n            - \"--disable-dev-shm-usage\"\n            - \"--proxy-server='direct://'\"\n            - \"--proxy-bypass-list=*\"\n            - \"--no-sandbox\"\n
                                                                                                                                                  "},{"location":"v3/modules/WPWebDriver/#public-api","title":"Public API","text":"
                                                                                                                                                  • acceptPopup() : void Accepts the active JavaScript native popup window, as created by window.alert|window.confirm|window.prompt. Don't confuse popups with modal windows, as created by various libraries.

                                                                                                                                                  • activatePlugin($pluginSlug) : void In the plugin administration screen activates one or more plugins clicking the \"Activate\" link.

                                                                                                                                                  The method will not handle authentication and navigation to the plugins administration page.

                                                                                                                                                  • activateTheme($slug) : void Activates a theme.

                                                                                                                                                  The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                  • amEditingPostWithId($id) : void Go to the admin page to edit the post with the specified ID.

                                                                                                                                                  The method will not handle authentication the admin area.

                                                                                                                                                  • amEditingUserWithId($id) : void Go to the admin page to edit the user with the specified ID.

                                                                                                                                                  The method will not handle authentication the admin area.

                                                                                                                                                  • amOnAdminAjaxPage([$queryVars]) : void Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.

                                                                                                                                                  The method will not handle authentication, nonces or authorization.

                                                                                                                                                  • amOnAdminPage($page) : void Go to a page in the admininstration area of the site.

                                                                                                                                                  This method will not handle authentication to the administration area.

                                                                                                                                                  • amOnCronPage([$queryVars]) : void Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

                                                                                                                                                  • amOnPage($page) : void

                                                                                                                                                  • amOnPagesPage() : void Go the \"Pages\" administration screen.

                                                                                                                                                  The method will not handle authentication.

                                                                                                                                                  • amOnPluginsPage() : void Go to the plugins administration screen.

                                                                                                                                                  The method will not handle authentication.

                                                                                                                                                  • amOnSubdomain($subdomain) : void

                                                                                                                                                  • amOnThemesPage() : void Moves to the themes administration page.

                                                                                                                                                  • amOnUrl($url) : void

                                                                                                                                                  • appendField($field, $value) : void Append the given text to the given element. Can also add a selection to a select box.

                                                                                                                                                  <?php\n$I->appendField('#mySelectbox', 'SelectValue');\n$I->appendField('#myTextField', 'appended');\n?>\n
                                                                                                                                                  • attachFile($field, $filename) : void

                                                                                                                                                  • cancelPopup() : void Dismisses the active JavaScript popup, as created by window.alert, window.confirm, or window.prompt.

                                                                                                                                                  • checkOption($option) : void

                                                                                                                                                  • clearField($field) : void Clears given field which isn't empty.

                                                                                                                                                  <?php\n$I->clearField('#username');\n
                                                                                                                                                  • click($link, [$context]) : void

                                                                                                                                                  • clickWithLeftButton([$cssOrXPath], [$offsetX], [$offsetY]) : void Performs click with the left mouse button on an element. If the first parameter null then the offset is relative to the actual mouse position. If the second and third parameters are given, then the mouse is moved to an offset of the element's top-left corner. Otherwise, the mouse is moved to the center of the element.

                                                                                                                                                  <?php\n$I->clickWithLeftButton(['css' => '.checkout']);\n$I->clickWithLeftButton(null, 20, 50);\n$I->clickWithLeftButton(['css' => '.checkout'], 20, 50);\n?>\n
                                                                                                                                                  • clickWithRightButton([$cssOrXPath], [$offsetX], [$offsetY]) : void Performs contextual click with the right mouse button on an element. If the first parameter null then the offset is relative to the actual mouse position. If the second and third parameters are given, then the mouse is moved to an offset of the element's top-left corner. Otherwise, the mouse is moved to the center of the element.
                                                                                                                                                  <?php\n$I->clickWithRightButton(['css' => '.checkout']);\n$I->clickWithRightButton(null, 20, 50);\n$I->clickWithRightButton(['css' => '.checkout'], 20, 50);\n?>\n
                                                                                                                                                  • closeTab() : void Closes current browser tab and switches to previous active tab.
                                                                                                                                                  <?php\n$I->closeTab();\n
                                                                                                                                                  • deactivatePlugin($pluginSlug) : void In the plugin administration screen deactivate a plugin clicking the \"Deactivate\" link.

                                                                                                                                                  The method will not handle authentication and navigation to the plugins administration page.

                                                                                                                                                  • debugWebDriverLogs([?Codeception\\TestInterface $test]) : void Print out latest Selenium Logs in debug mode

                                                                                                                                                  • deleteSessionSnapshot($name) : void

                                                                                                                                                  • dontSee($text, [$selector]) : void

                                                                                                                                                  • dontSeeCheckboxIsChecked($checkbox) : void

                                                                                                                                                  • dontSeeCookie($cookie, [array $params]) : void

                                                                                                                                                  • dontSeeCurrentUrlEquals($uri) : void

                                                                                                                                                  • dontSeeCurrentUrlMatches($uri) : void

                                                                                                                                                  • dontSeeElement($selector, [$attributes]) : void

                                                                                                                                                  • dontSeeElementInDOM($selector, [$attributes]) : void Opposite of seeElementInDOM.

                                                                                                                                                  • dontSeeInCurrentUrl($uri) : void

                                                                                                                                                  • dontSeeInField($field, $value) : void

                                                                                                                                                  • dontSeeInFormFields($formSelector, array $params) : void

                                                                                                                                                  • dontSeeInPageSource($text) : void Checks that the page source doesn't contain the given string.

                                                                                                                                                  • dontSeeInPopup($text) : void Checks that the active JavaScript popup, as created by window.alert|window.confirm|window.prompt, does NOT contain the given string.

                                                                                                                                                  • dontSeeInSource($raw) : void

                                                                                                                                                  • dontSeeInTitle($title) : void

                                                                                                                                                  • dontSeeLink($text, [$url]) : void

                                                                                                                                                  • dontSeeOptionIsSelected($selector, $optionText) : void

                                                                                                                                                  • dontSeePluginInstalled($pluginSlug) : void Assert a plugin is not installed in the plugins administration screen.

                                                                                                                                                  The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                  • doubleClick($cssOrXPath) : void Performs a double-click on an element matched by CSS or XPath.

                                                                                                                                                  • dragAndDrop($source, $target) : void Performs a simple mouse drag-and-drop operation.

                                                                                                                                                  <?php\n$I->dragAndDrop('#drag', '#drop');\n?>\n
                                                                                                                                                  • executeAsyncJS($script, [array $arguments]) : void Executes asynchronous JavaScript. A callback should be executed by JavaScript to exit from a script. Callback is passed as a last element in arguments array. Additional arguments can be passed as array in second parameter.
                                                                                                                                                  // wait for 1200 milliseconds my running `setTimeout`\n* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');\n\n$seconds = 1200; // or seconds are passed as argument\n$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);\n
                                                                                                                                                  • executeInSelenium(Closure $function) : void Low-level API method. If Codeception commands are not enough, this allows you to use Selenium WebDriver methods directly:
                                                                                                                                                  $I->executeInSelenium(function(\\Facebook\\WebDriver\\Remote\\RemoteWebDriver $webdriver) {\n  $webdriver->get('http://google.com');\n});\n

                                                                                                                                                  This runs in the context of the RemoteWebDriver class. Try not to use this command on a regular basis. If Codeception lacks a feature you need, please implement it and submit a patch.

                                                                                                                                                  • executeJS($script, [array $arguments]) : void Executes custom JavaScript.

                                                                                                                                                  This example uses jQuery to get a value and assigns that value to a PHP variable:

                                                                                                                                                  <?php\n$myVar = $I->executeJS('return $(\"#myField\").val()');\n\n// additional arguments can be passed as array\n// Example shows `Hello World` alert:\n$I->executeJS(\"window.alert(arguments[0])\", ['Hello world']);\n
                                                                                                                                                  • fillField($field, $value) : void

                                                                                                                                                  • grabActiveTheme() : void Returns the slug of the currently active themes.

                                                                                                                                                  The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                  • grabAttributeFrom($cssOrXpath, $attribute) : void

                                                                                                                                                  • grabAvailableThemes([$classes]) : void Returns the list of available themes.

                                                                                                                                                  The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                  • grabCookie($cookie, [array $params]) : void

                                                                                                                                                  • grabCookiesWithPattern($cookiePattern) : void Returns all the cookies whose name matches a regex pattern.

                                                                                                                                                  • grabFromCurrentUrl([$uri]) : void

                                                                                                                                                  • grabFullUrl() : void Grabs the current page full URL including the query vars.

                                                                                                                                                  • grabMultiple($cssOrXpath, [$attribute]) : void

                                                                                                                                                  • grabPageSource() : void Grabs current page source code.

                                                                                                                                                  • grabTextFrom($cssOrXPathOrRegex) : void

                                                                                                                                                  • grabValueFrom($field) : void

                                                                                                                                                  • grabWordPressTestCookie([$name]) : void Returns WordPress default test cookie object if present.

                                                                                                                                                  • loadSessionSnapshot($name) : void

                                                                                                                                                  • logOut([$redirectTo]) : void Navigate to the default WordPress logout page and click the logout link.

                                                                                                                                                  • loginAs($username, $password, [$timeout], [$maxAttempts]) : void Login as the specified user.

                                                                                                                                                  The method will not follow redirection, after the login, to any page. Depending on the driven browser the login might be \"too fast\" and the server might have not replied with valid cookies yet; in that case the method will re-attempt the login to obtain the cookies.

                                                                                                                                                  • loginAsAdmin([$timeout], [$maxAttempts]) : void Login as the administrator user using the credentials specified in the module configuration.

                                                                                                                                                  The method will not follow redirection, after the login, to any page.

                                                                                                                                                  • makeElementScreenshot($selector, [$name]) : void Takes a screenshot of an element of the current window and saves it to tests/_output/debug.
                                                                                                                                                  <?php\n$I->amOnPage('/user/edit');\n$I->makeElementScreenshot('#dialog', 'edit_page');\n// saved to: tests/_output/debug/edit_page.png\n$I->makeElementScreenshot('#dialog');\n// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png\n
                                                                                                                                                  • makeHtmlSnapshot([$name]) : void

                                                                                                                                                  • makeScreenshot([$name]) : void Takes a screenshot of the current window and saves it to tests/_output/debug.

                                                                                                                                                  <?php\n$I->amOnPage('/user/edit');\n$I->makeScreenshot('edit_page');\n// saved to: tests/_output/debug/edit_page.png\n$I->makeScreenshot();\n// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png\n
                                                                                                                                                  • maximizeWindow() : void Maximizes the current window.

                                                                                                                                                  • moveBack() : void Moves back in history.

                                                                                                                                                  • moveForward() : void Moves forward in history.

                                                                                                                                                  • moveMouseOver([$cssOrXPath], [$offsetX], [$offsetY]) : void Move mouse over the first element matched by the given locator. If the first parameter null then the page is used. If the second and third parameters are given, then the mouse is moved to an offset of the element's top-left corner. Otherwise, the mouse is moved to the center of the element.

                                                                                                                                                  <?php\n$I->moveMouseOver(['css' => '.checkout']);\n$I->moveMouseOver(null, 20, 50);\n$I->moveMouseOver(['css' => '.checkout'], 20, 50);\n?>\n
                                                                                                                                                  • openNewTab() : void Opens a new browser tab and switches to it.

                                                                                                                                                  <?php\n$I->openNewTab();\n
                                                                                                                                                  The tab is opened with JavaScript's window.open(), which means: * Some adblockers might restrict it. * The sessionStorage is copied to the new tab (contrary to a tab that was manually opened by the user)

                                                                                                                                                  • performOn($element, $actions, [$timeout]) : void Waits for element and runs a sequence of actions inside its context. Actions can be defined with array, callback, or Codeception\\Util\\ActionSequence instance.

                                                                                                                                                  Actions as array are recommended for simple to combine \"waitForElement\" with assertions; waitForElement($el) and see('text', $el) can be simplified to:

                                                                                                                                                  <?php\n$I->performOn($el, ['see' => 'text']);\n

                                                                                                                                                  List of actions can be pragmatically build using Codeception\\Util\\ActionSequence:

                                                                                                                                                  <?php\n$I->performOn('.model', ActionSequence::build()\n    ->see('Warning')\n    ->see('Are you sure you want to delete this?')\n    ->click('Yes')\n);\n

                                                                                                                                                  Actions executed from array or ActionSequence will print debug output for actions, and adds an action name to exception on failure.

                                                                                                                                                  Whenever you need to define more actions a callback can be used. A WebDriver module is passed for argument:

                                                                                                                                                  <?php\n$I->performOn('.rememberMe', function (WebDriver $I) {\n     $I->see('Remember me next time');\n     $I->seeElement('#LoginForm_rememberMe');\n     $I->dontSee('Login');\n});\n

                                                                                                                                                  In 3rd argument you can set number a seconds to wait for element to appear

                                                                                                                                                  • pressKey($element, $char) : void Presses the given key on the given element. To specify a character and modifier (e.g. Ctrl, Alt, Shift, Meta), pass an array for $char with the modifier as the first element and the character as the second. For special keys, use the constants from Facebook\\WebDriver\\WebDriverKeys.
                                                                                                                                                  <?php\n// <input id=\"page\" value=\"old\" />\n$I->pressKey('#page','a'); // => olda\n$I->pressKey('#page',array('ctrl','a'),'new'); //=> new\n$I->pressKey('#page',array('shift','111'),'1','x'); //=> old!!!1x\n$I->pressKey('descendant-or-self::*[@id='page']','u'); //=> oldu\n$I->pressKey('#name', array('ctrl', 'a'), \\Facebook\\WebDriver\\WebDriverKeys::DELETE); //=>''\n?>\n
                                                                                                                                                  • reloadPage() : void Reloads the current page.

                                                                                                                                                  • resetCookie($cookie, [array $params]) : void

                                                                                                                                                  • resizeWindow($width, $height) : void Resize the current window.

                                                                                                                                                  <?php\n$I->resizeWindow(800, 600);\n
                                                                                                                                                  • saveSessionSnapshot($name) : void

                                                                                                                                                  • scrollTo($selector, [$offsetX], [$offsetY]) : void Move to the middle of the given element matched by the given locator. Extra shift, calculated from the top-left corner of the element, can be set by passing $offsetX and $offsetY parameters.

                                                                                                                                                  <?php\n$I->scrollTo(['css' => '.checkout'], 20, 50);\n?>\n
                                                                                                                                                  • see($text, [$selector]) : void

                                                                                                                                                  • seeCheckboxIsChecked($checkbox) : void

                                                                                                                                                  • seeCookie($cookie, [array $params]) : void

                                                                                                                                                  • seeCurrentUrlEquals($uri) : void

                                                                                                                                                  • seeCurrentUrlMatches($uri) : void

                                                                                                                                                  • seeElement($selector, [$attributes]) : void

                                                                                                                                                  • seeElementInDOM($selector, [$attributes]) : void Checks that the given element exists on the page, even it is invisible.

                                                                                                                                                  <?php\n$I->seeElementInDOM('//form/input[type=hidden]');\n?>\n
                                                                                                                                                  • seeErrorMessage([$classes]) : void In an administration screen look for an error admin notice.

                                                                                                                                                  The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

                                                                                                                                                  • seeInCurrentUrl($uri) : void

                                                                                                                                                  • seeInField($field, $value) : void

                                                                                                                                                  • seeInFormFields($formSelector, array $params) : void

                                                                                                                                                  • seeInPageSource($text) : void Checks that the page source contains the given string.

                                                                                                                                                  <?php\n$I->seeInPageSource('<link rel=\"apple-touch-icon\"');\n
                                                                                                                                                  • seeInPopup($text) : void Checks that the active JavaScript popup, as created by window.alert|window.confirm|window.prompt, contains the given string.

                                                                                                                                                  • seeInSource($raw) : void

                                                                                                                                                  • seeInTitle($title) : void

                                                                                                                                                  • seeLink($text, [$url]) : void

                                                                                                                                                  • seeMessage([$classes]) : void In an administration screen look for an admin notice.

                                                                                                                                                  The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

                                                                                                                                                  • seeNumberOfElements($selector, $expected) : void

                                                                                                                                                  • seeNumberOfElementsInDOM($selector, $expected) : void

                                                                                                                                                  • seeNumberOfTabs($number) : void Checks current number of opened tabs

                                                                                                                                                  <?php\n$I->seeNumberOfTabs(2);\n
                                                                                                                                                  • seeOptionIsSelected($selector, $optionText) : void

                                                                                                                                                  • seePluginActivated($pluginSlug) : void Assert a plugin is activated in the plugin administration screen.

                                                                                                                                                  The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                  • seePluginDeactivated($pluginSlug) : void Assert a plugin is not activated in the plugins administration screen.

                                                                                                                                                  The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                  • seePluginInstalled($pluginSlug) : void Assert a plugin is installed, no matter its activation status, in the plugin administration screen.

                                                                                                                                                  The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                  • seeThemeActivated($slug) : void Verifies that a theme is active.

                                                                                                                                                  The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                  • seeWpDiePage() : void Checks that the current page is one generated by the wp_die function.

                                                                                                                                                  The method will try to identify the page based on the default WordPress die page HTML attributes.

                                                                                                                                                  • selectOption($select, $option) : void

                                                                                                                                                  • setCookie($cookie, $value, [array $params], [$showDebug]) : void

                                                                                                                                                  • submitForm($selector, array $params, [$button]) : void Submits the given form on the page, optionally with the given form values. Give the form fields values as an array. Note that hidden fields can't be accessed.

                                                                                                                                                  Skipped fields will be filled by their values from the page. You don't need to click the 'Submit' button afterwards. This command itself triggers the request to form's action.

                                                                                                                                                  You can optionally specify what button's value to include in the request with the last parameter as an alternative to explicitly setting its value in the second parameter, as button values are not otherwise included in the request.

                                                                                                                                                  Examples:

                                                                                                                                                  <?php\n$I->submitForm('#login', [\n    'login' => 'davert',\n    'password' => '123456'\n]);\n// or\n$I->submitForm('#login', [\n    'login' => 'davert',\n    'password' => '123456'\n], 'submitButtonName');\n

                                                                                                                                                  For example, given this sample \"Sign Up\" form:

                                                                                                                                                  <form action=\"/sign_up\">\n    Login:\n    <input type=\"text\" name=\"user[login]\" /><br/>\n    Password:\n    <input type=\"password\" name=\"user[password]\" /><br/>\n    Do you agree to our terms?\n    <input type=\"checkbox\" name=\"user[agree]\" /><br/>\n    Select pricing plan:\n    <select name=\"plan\">\n        <option value=\"1\">Free</option>\n        <option value=\"2\" selected=\"selected\">Paid</option>\n    </select>\n    <input type=\"submit\" name=\"submitButton\" value=\"Submit\" />\n</form>\n

                                                                                                                                                  You could write the following to submit it:

                                                                                                                                                  <?php\n$I->submitForm(\n    '#userForm',\n    [\n        'user[login]' => 'Davert',\n        'user[password]' => '123456',\n        'user[agree]' => true\n    ],\n    'submitButton'\n);\n
                                                                                                                                                  Note that \"2\" will be the submitted value for the \"plan\" field, as it is the selected option.

                                                                                                                                                  Also note that this differs from PhpBrowser, in that 'user' => [ 'login' => 'Davert' ] is not supported at the moment. Named array keys must be included in the name as above.

                                                                                                                                                  Pair this with seeInFormFields for quick testing magic.

                                                                                                                                                  <?php\n$form = [\n     'field1' => 'value',\n     'field2' => 'another value',\n     'checkbox1' => true,\n     // ...\n];\n$I->submitForm('//form[@id=my-form]', $form, 'submitButton');\n// $I->amOnPage('/path/to/form-page') may be needed\n$I->seeInFormFields('//form[@id=my-form]', $form);\n?>\n

                                                                                                                                                  Parameter values must be set to arrays for multiple input fields of the same name, or multi-select combo boxes. For checkboxes, either the string value can be used, or boolean values which will be replaced by the checkbox's value in the DOM.

                                                                                                                                                  <?php\n$I->submitForm('#my-form', [\n     'field1' => 'value',\n     'checkbox' => [\n         'value of first checkbox',\n         'value of second checkbox',\n     ],\n     'otherCheckboxes' => [\n         true,\n         false,\n         false,\n     ],\n     'multiselect' => [\n         'first option value',\n         'second option value',\n     ]\n]);\n?>\n

                                                                                                                                                  Mixing string and boolean values for a checkbox's value is not supported and may produce unexpected results.

                                                                                                                                                  Field names ending in \"[]\" must be passed without the trailing square bracket characters, and must contain an array for its value. This allows submitting multiple values with the same name, consider:

                                                                                                                                                  $I->submitForm('#my-form', [\n    'field[]' => 'value',\n    'field[]' => 'another value', // 'field[]' is already a defined key\n]);\n

                                                                                                                                                  The solution is to pass an array value:

                                                                                                                                                  // this way both values are submitted\n$I->submitForm('#my-form', [\n    'field' => [\n        'value',\n        'another value',\n    ]\n]);\n

                                                                                                                                                  The $button parameter can be either a string, an array or an instance of Facebook\\WebDriver\\WebDriverBy. When it is a string, the button will be found by its \"name\" attribute. If $button is an array then it will be treated as a strict selector and a WebDriverBy will be used verbatim.

                                                                                                                                                  For example, given the following HTML:

                                                                                                                                                  <input type=\"submit\" name=\"submitButton\" value=\"Submit\" />\n

                                                                                                                                                  $button could be any one of the following: - 'submitButton' - ['name' => 'submitButton'] - WebDriverBy::name('submitButton')

                                                                                                                                                  • switchToFrame([$locator]) : void Switch to another frame on the page.

                                                                                                                                                  Example:

                                                                                                                                                  <frame name=\"another_frame\" id=\"fr1\" src=\"http://example.com\">\n

                                                                                                                                                  <?php\n# switch to frame by name\n$I->switchToFrame(\"another_frame\");\n# switch to frame by CSS or XPath\n$I->switchToFrame(\"#fr1\");\n# switch to parent page\n$I->switchToFrame();\n
                                                                                                                                                  • switchToIFrame([$locator]) : void Switch to another iframe on the page.

                                                                                                                                                  Example:

                                                                                                                                                  <iframe name=\"another_frame\" id=\"fr1\" src=\"http://example.com\">\n

                                                                                                                                                  <?php\n# switch to iframe by name\n$I->switchToIFrame(\"another_frame\");\n# switch to iframe by CSS or XPath\n$I->switchToIFrame(\"#fr1\");\n# switch to parent page\n$I->switchToIFrame();\n
                                                                                                                                                  • switchToNextTab([$offset]) : void Switches to next browser tab. An offset can be specified.
                                                                                                                                                  <?php\n// switch to next tab\n$I->switchToNextTab();\n// switch to 2nd next tab\n$I->switchToNextTab(2);\n
                                                                                                                                                  • switchToPreviousTab([$offset]) : void Switches to previous browser tab. An offset can be specified.
                                                                                                                                                  <?php\n// switch to previous tab\n$I->switchToPreviousTab();\n// switch to 2nd previous tab\n$I->switchToPreviousTab(2);\n
                                                                                                                                                  • switchToWindow([$name]) : void Switch to another window identified by name.

                                                                                                                                                  The window can only be identified by name. If the $name parameter is blank, the parent window will be used.

                                                                                                                                                  Example:

                                                                                                                                                  <input type=\"button\" value=\"Open window\" onclick=\"window.open('http://example.com', 'another_window')\">\n

                                                                                                                                                  <?php\n$I->click(\"Open window\");\n# switch to another window\n$I->switchToWindow(\"another_window\");\n# switch to parent window\n$I->switchToWindow();\n?>\n

                                                                                                                                                  If the window has no name, match it by switching to next active tab using switchToNextTab method.

                                                                                                                                                  Or use native Selenium functions to get access to all opened windows:

                                                                                                                                                  <?php\n$I->executeInSelenium(function (\\Facebook\\WebDriver\\Remote\\RemoteWebDriver $webdriver) {\n     $handles=$webdriver->getWindowHandles();\n     $last_window = end($handles);\n     $webdriver->switchTo()->window($last_window);\n});\n?>\n
                                                                                                                                                  • type($text, [$delay]) : void Type in characters on active element. With a second parameter you can specify delay between key presses.
                                                                                                                                                  <?php\n// activate input element\n$I->click('#input');\n\n// type text in active element\n$I->type('Hello world');\n\n// type text with a 1sec delay between chars\n$I->type('Hello World', 1);\n

                                                                                                                                                  This might be useful when you an input reacts to typing and you need to slow it down to emulate human behavior. For instance, this is how Credit Card fields can be filled in.

                                                                                                                                                  • typeInPopup($keys) : void Enters text into a native JavaScript prompt popup, as created by window.prompt.

                                                                                                                                                  • uncheckOption($option) : void

                                                                                                                                                  • unselectOption($select, $option) : void Unselect an option in the given select box.

                                                                                                                                                  • wait($timeout) : void Wait for $timeout seconds.

                                                                                                                                                  • waitForElement($element, [$timeout]) : void Waits up to $timeout seconds for an element to appear on the page. If the element doesn't appear, a timeout exception is thrown.

                                                                                                                                                  <?php\n$I->waitForElement('#agree_button', 30); // secs\n$I->click('#agree_button');\n?>\n
                                                                                                                                                  • waitForElementChange($element, Closure $callback, [$timeout]) : void Waits up to $timeout seconds for the given element to change. Element \"change\" is determined by a callback function which is called repeatedly until the return value evaluates to true.
                                                                                                                                                  <?php\nuse \\Facebook\\WebDriver\\WebDriverElement\n$I->waitForElementChange('#menu', function(WebDriverElement $el) {\n    return $el->isDisplayed();\n}, 100);\n?>\n
                                                                                                                                                  • waitForElementClickable($element, [$timeout]) : void Waits up to $timeout seconds for the given element to be clickable. If element doesn't become clickable, a timeout exception is thrown.
                                                                                                                                                  <?php\n$I->waitForElementClickable('#agree_button', 30); // secs\n$I->click('#agree_button');\n?>\n
                                                                                                                                                  • waitForElementNotVisible($element, [$timeout]) : void Waits up to $timeout seconds for the given element to become invisible. If element stays visible, a timeout exception is thrown.
                                                                                                                                                  <?php\n$I->waitForElementNotVisible('#agree_button', 30); // secs\n?>\n
                                                                                                                                                  • waitForElementVisible($element, [$timeout]) : void Waits up to $timeout seconds for the given element to be visible on the page. If element doesn't appear, a timeout exception is thrown.
                                                                                                                                                  <?php\n$I->waitForElementVisible('#agree_button', 30); // secs\n$I->click('#agree_button');\n?>\n
                                                                                                                                                  • waitForJS($script, [$timeout]) : void Executes JavaScript and waits up to $timeout seconds for it to return true.

                                                                                                                                                  In this example we will wait up to 60 seconds for all jQuery AJAX requests to finish.

                                                                                                                                                  <?php\n$I->waitForJS(\"return $.active == 0;\", 60);\n?>\n
                                                                                                                                                  • waitForJqueryAjax([$time]) : void Waits for any jQuery triggered AJAX request to be resolved.

                                                                                                                                                  • waitForText($text, [$timeout], [$selector]) : void Waits up to $timeout seconds for the given string to appear on the page.

                                                                                                                                                  Can also be passed a selector to search in, be as specific as possible when using selectors. waitForText() will only watch the first instance of the matching selector / text provided. If the given text doesn't appear, a timeout exception is thrown.

                                                                                                                                                  <?php\n$I->waitForText('foo', 30); // secs\n$I->waitForText('foo', 30, '.title'); // secs\n?>\n

                                                                                                                                                  This class extends \\Codeception\\Module\\WebDriver

                                                                                                                                                  This class implements \\Codeception\\Lib\\Interfaces\\RequiresPackage, \\Codeception\\Lib\\Interfaces\\ConflictsWithModule, \\Codeception\\Lib\\Interfaces\\ElementLocator, \\Codeception\\Lib\\Interfaces\\PageSourceSaver, \\Codeception\\Lib\\Interfaces\\ScreenshotSaver, \\Codeception\\Lib\\Interfaces\\SessionSnapshot, \\Codeception\\Lib\\Interfaces\\MultiSession, \\Codeception\\Lib\\Interfaces\\Remote, \\Codeception\\Lib\\Interfaces\\Web

                                                                                                                                                  "},{"location":"v3/modules/WordPress/","title":"WordPress","text":"

                                                                                                                                                  This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                  "},{"location":"v3/modules/WordPress/#wordpress-module","title":"WordPress module","text":"

                                                                                                                                                  This module requires good knowledge and attention to be used effectively; you can replace it with a combination of the WPBrowser module together with the WPLoader module in loadOnly mode. This module should be used in functional tests, see levels of testing for more information. This module provides a middle-ground, in terms of testing and effects, between the fully isolated approach of the WPBrowser module and the fully integrated approach of the WPLoader module with loadOnly set to false. It allows to interact with WordPress on a very high level, using methods like $I->loginAs() or $I->amOnPage() as you could do with the WPBrowser module while also loading WordPress in the same variable scope as the tests as the WPLoader module would. Due to WordPress reliance on constants, globals and side-effects this module will make requests to WordPress in an insulated manner and reproduce WordPress environment (globals and super-globals) after each response in the tests variable scope. The module simulates a user interaction with the site without Javascript support, use the WPWebDriver module for any kind of testing that requires Javascript-based interaction with the site.

                                                                                                                                                  "},{"location":"v3/modules/WordPress/#module-requirements-for-codeception-40","title":"Module requirements for Codeception 4.0+","text":"

                                                                                                                                                  This module requires the codeception/lib-innerbrowser Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                  To install the package run:

                                                                                                                                                  composer require --dev codeception/lib-innerbrowser:^1.0\n
                                                                                                                                                  "},{"location":"v3/modules/WordPress/#detecting-requests-coming-from-this-module","title":"Detecting requests coming from this module","text":"

                                                                                                                                                  When it runs this module will set the WPBROWSER_HOST_REQUEST environment variable. You can detect and use that information to, as an example, use the correct database in your test site wp-config.php file:

                                                                                                                                                  <?php\nif ( \n    // Custom header.\n    isset( $_SERVER['HTTP_X_TESTING'] )\n    // Custom user agent.\n    || ( isset( $_SERVER['HTTP_USER_AGENT'] ) && $_SERVER['HTTP_USER_AGENT'] === 'wp-browser' )\n    // The env var set by the WPClIr or WordPress modules.\n    || getenv( 'WPBROWSER_HOST_REQUEST' )\n) {\n    // Use the test database if the request comes from a test.\n    define( 'DB_NAME', 'wordpress_test' );\n} else {\n    // Else use the default one.\n    define( 'DB_NAME', 'wordpress' );\n}\n

                                                                                                                                                  "},{"location":"v3/modules/WordPress/#configuration","title":"Configuration","text":"
                                                                                                                                                  • wpRootFolder required The absolute, or relative to the project root folder, path to the root WordPress installation folder. The WordPress installation root folder is the one that contains the wp-load.php file.
                                                                                                                                                  • adminUsername required - This is the login name, not the \"nice\" name, of the administrator user of the WordPress test site. This will be used to fill the username field in WordPress login page.
                                                                                                                                                  • adminPassword required - This is the the password of the administrator use of the WordPress test site. This will be used to fill the password in WordPress login page.
                                                                                                                                                  • adminPath required - The path, relative to the WordPress test site home URL, to the administration area, usually /wp-admin.
                                                                                                                                                  "},{"location":"v3/modules/WordPress/#example-configuration","title":"Example configuration","text":"
                                                                                                                                                    modules:\n      enabled:\n          - WordPress\n      config:\n          WordPress:\n              wpRootFolder: \"/var/www/wordpress\"\n              adminUsername: 'admin'\n              adminPassword: 'password'\n              adminPath: '/wp-admin'\n
                                                                                                                                                  "},{"location":"v3/modules/WordPress/#public-api","title":"Public API","text":"
                                                                                                                                                  • amEditingPostWithId
                                                                                                                                                  • amOnAdminAjaxPage
                                                                                                                                                  • amOnAdminPage
                                                                                                                                                  • amOnCronPage
                                                                                                                                                  • amOnPage
                                                                                                                                                  • amOnPagesPage
                                                                                                                                                  • amOnPluginsPage
                                                                                                                                                  • dontSeePluginInstalled
                                                                                                                                                  • extractCookie
                                                                                                                                                  • getResponseContent
                                                                                                                                                  • getWpRootFolder
                                                                                                                                                  • grabWordPressTestCookie
                                                                                                                                                  • logOut
                                                                                                                                                  • loginAs
                                                                                                                                                  • loginAsAdmin
                                                                                                                                                  • seeErrorMessage
                                                                                                                                                  • seeMessage
                                                                                                                                                  • seePluginActivated
                                                                                                                                                  • seePluginDeactivated
                                                                                                                                                  • seePluginInstalled
                                                                                                                                                  • seeWpDiePage
                                                                                                                                                  amEditingPostWithId

                                                                                                                                                  Go to the admin page to edit the post with the specified ID. The method will not handle authentication the admin area.

                                                                                                                                                  $I->loginAsAdmin();\n  $postId = $I->havePostInDatabase();\n  $I->amEditingPostWithId($postId);\n  $I->fillField('post_title', 'Post title');\n
                                                                                                                                                  Parameters
                                                                                                                                                  • int $id - The post ID.
                                                                                                                                                  amOnAdminAjaxPage

                                                                                                                                                  Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request. The method will not handle authentication, nonces or authorization.

                                                                                                                                                  $I->amOnAdminAjaxPage(['action' => 'my-action', 'data' => ['id' => 23], 'nonce' => $nonce]);\n
                                                                                                                                                  Parameters
                                                                                                                                                  • string/\\Codeception\\Module\\array $queryVars - A string or array of query variables to append to the AJAX path. amOnAdminPage

                                                                                                                                                    Go to a page in the admininstration area of the site.

                                                                                                                                                    $I->loginAs('user', 'password');\n  // Go to the plugins management screen.\n  $I->amOnAdminPage('/plugins.php');\n
                                                                                                                                                    Parameters
                                                                                                                                                    • string $page - The path, relative to the admin area URL, to the page.
                                                                                                                                                    amOnCronPage

                                                                                                                                                    Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

                                                                                                                                                    // Triggers the cron job with an optional query argument.\n  $I->amOnCronPage('/?some-query-var=some-value');\n
                                                                                                                                                    Parameters
                                                                                                                                                    • string/\\Codeception\\Module\\array $queryVars - A string or array of query variables to append to the AJAX path. amOnPage

                                                                                                                                                      Go to a page on the site. The module will try to reach the page, relative to the URL specified in the module configuration, without applying any permalink resolution.

                                                                                                                                                      // Go the the homepage.\n  $I->amOnPage('/');\n  // Go to the single page of post with ID 23.\n  $I->amOnPage('/?p=23');\n  // Go to search page for the string \"foo\".\n  $I->amOnPage('/?s=foo');\n
                                                                                                                                                      Parameters
                                                                                                                                                      • string $page - The path to the page, relative to the the root URL.
                                                                                                                                                      amOnPagesPage

                                                                                                                                                      Go the \"Pages\" administration screen. The method will not handle authentication.

                                                                                                                                                      $I->loginAsAdmin();\n  $I->amOnPagesPage();\n  $I->see('Add New');\n
                                                                                                                                                      amOnPluginsPage

                                                                                                                                                      Go to the plugins administration screen. The method will not handle authentication.

                                                                                                                                                      $I->loginAsAdmin();\n  $I->amOnPluginsPage();\n  $I->activatePlugin('hello-dolly');\n
                                                                                                                                                      dontSeePluginInstalled

                                                                                                                                                      Assert a plugin is not installed in the plugins administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                      $I->loginAsAdmin();\n  $I->amOnPluginsPage();\n  $I->dontSeePluginInstalled('my-plugin');\n
                                                                                                                                                      Parameters
                                                                                                                                                      • string $pluginSlug - The plugin slug, like \"hello-dolly\".
                                                                                                                                                      extractCookie

                                                                                                                                                      Grab a cookie value from the current session, sets it in the $_COOKIE array and returns its value. This method utility is to get, in the scope of test code, the value of a cookie set during the tests.

                                                                                                                                                      $id = $I->haveUserInDatabase('user', 'subscriber', ['user_pass' => 'pass']);\n  $I->loginAs('user', 'pass');\n  // The cookie is now set in the `$_COOKIE` super-global.\n  $I->extractCookie(LOGGED_IN_COOKIE);\n  // Generate a nonce using WordPress methods (see WPLoader in loadOnly mode) with correctly set context.\n  wp_set_current_user($id);\n  $nonce = wp_create_nonce('wp_rest');\n  // Use the generated nonce to make a request to the the REST API.\n  $I->haveHttpHeader('X-WP-Nonce', $nonce);\n
                                                                                                                                                      Parameters
                                                                                                                                                      • string $cookie - The cookie name.
                                                                                                                                                      • array/\\Codeception\\Module\\array/array $params - Parameters to filter the cookie value. getResponseContent

                                                                                                                                                        Returns content of the last response. This method exposes an underlying API for custom assertions.

                                                                                                                                                        // In test class.\n  $this->assertContains($text, $this->getResponseContent(), \"foo-bar\");\n
                                                                                                                                                        getWpRootFolder

                                                                                                                                                        Returns the absolute path to the WordPress root folder.

                                                                                                                                                        $root = $I->getWpRootFolder();\n  $this->assertFileExists($root . '/someFile.txt');\n
                                                                                                                                                        grabWordPressTestCookie

                                                                                                                                                        Returns WordPress default test cookie object if present.

                                                                                                                                                        // Grab the default WordPress test cookie.\n  $wpTestCookie = $I->grabWordPressTestCookie();\n  // Grab a customized version of the test cookie.\n  $myTestCookie = $I->grabWordPressTestCookie('my_test_cookie');\n
                                                                                                                                                        Parameters
                                                                                                                                                        • string $name - Optional, overrides the default cookie name.
                                                                                                                                                        logOut

                                                                                                                                                        Navigate to the default WordPress logout page and click the logout link.

                                                                                                                                                        // Log out using the `wp-login.php` form and return to the current page.\n  $I->logOut(true);\n  // Log out using the `wp-login.php` form and remain there.\n  $I->logOut(false);\n  // Log out using the `wp-login.php` form and move to another page.\n  $I->logOut('/some-other-page');\n
                                                                                                                                                        Parameters
                                                                                                                                                        • bool/bool/string $redirectTo - Whether to redirect to another (optionally specified) page after the logout.
                                                                                                                                                        loginAs

                                                                                                                                                        Login as the specified user. The method will not follow redirection, after the login, to any page.

                                                                                                                                                        $I->loginAs('user', 'password');\n  $I->amOnAdminPage('/');\n  $I->seeElement('.admin');\n
                                                                                                                                                        Parameters
                                                                                                                                                        • string $username - The user login name.
                                                                                                                                                        • string $password - The user password in plain text.
                                                                                                                                                        loginAsAdmin

                                                                                                                                                        Login as the administrator user using the credentials specified in the module configuration. The method will not follow redirection, after the login, to any page.

                                                                                                                                                        $I->loginAsAdmin();\n  $I->amOnAdminPage('/');\n  $I->see('Dashboard');\n
                                                                                                                                                        seeErrorMessage

                                                                                                                                                        In an administration screen look for an error admin notice. The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area. .notice.notice-error ones.

                                                                                                                                                        $I->loginAsAdmin()\n  $I->amOnAdminPage('/');\n  $I->seeErrorMessage('.my-plugin');\n
                                                                                                                                                        Parameters
                                                                                                                                                        • string/string/\\Codeception\\Module\\array $classes - A list of classes the notice should have other than the seeMessage

                                                                                                                                                          In an administration screen look for an admin notice. The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

                                                                                                                                                          $I->loginAsAdmin()\n  $I->amOnAdminPage('/');\n  $I->seeMessage('.missing-api-token.my-plugin');\n
                                                                                                                                                          Parameters
                                                                                                                                                          • string/\\Codeception\\Module\\array/string $classes - A list of classes the message should have in addition to the .notice one. seePluginActivated

                                                                                                                                                            Assert a plugin is activated in the plugin administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            $I->loginAsAdmin();\n  $I->amOnPluginsPage();\n  $I->seePluginActivated('my-plugin');\n
                                                                                                                                                            Parameters
                                                                                                                                                            • string $pluginSlug - The plugin slug, like \"hello-dolly\".
                                                                                                                                                            seePluginDeactivated

                                                                                                                                                            Assert a plugin is not activated in the plugins administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            $I->loginAsAdmin();\n  $I->amOnPluginsPage();\n  $I->seePluginDeactivated('my-plugin');\n
                                                                                                                                                            Parameters
                                                                                                                                                            • string $pluginSlug - The plugin slug, like \"hello-dolly\".
                                                                                                                                                            seePluginInstalled

                                                                                                                                                            Assert a plugin is installed, no matter its activation status, in the plugin administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            $I->loginAsAdmin();\n  $I->amOnPluginsPage();\n  $I->seePluginInstalled('my-plugin');\n
                                                                                                                                                            Parameters
                                                                                                                                                            • string $pluginSlug - The plugin slug, like \"hello-dolly\".
                                                                                                                                                            seeWpDiePage

                                                                                                                                                            Checks that the current page is one generated by the wp_die function. The method will try to identify the page based on the default WordPress die page HTML attributes.

                                                                                                                                                            $I->loginAs('user', 'password');\n  $I->amOnAdminPage('/forbidden');\n  $I->seeWpDiePage();\n

                                                                                                                                                            This class extends \\Codeception\\Lib\\Framework

                                                                                                                                                            This class implements \\Codeception\\Lib\\Interfaces\\Web, \\Codeception\\Lib\\Interfaces\\PageSourceSaver, \\Codeception\\Lib\\Interfaces\\ElementLocator, \\Codeception\\Lib\\Interfaces\\ConflictsWithModule, \\Codeception\\Lib\\Interfaces\\DependsOnModule

                                                                                                                                                            "},{"location":"v3/tutorials/automatically-change-db-in-tests/","title":"Automatically change database during acceptance and functional tests","text":"

                                                                                                                                                            This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                            "},{"location":"v3/tutorials/automatically-change-db-in-tests/#automatically-change-database-during-acceptance-and-functional-tests","title":"Automatically change database during acceptance and functional tests","text":"

                                                                                                                                                            You should always back up any site you run tests on if you care about the site content.

                                                                                                                                                            Now this disclaimer has been made ad nauseam; there's a simple way to use a different database when during tests.

                                                                                                                                                            "},{"location":"v3/tutorials/automatically-change-db-in-tests/#identifying-requests","title":"Identifying requests","text":"

                                                                                                                                                            The first component of this solution is identifying the source of the current HTTP request. WordPress makes this identification before deciding which database to use.

                                                                                                                                                            To provide the WordPress installation with this information, you can set the headers entry of the WPBrowser or WPWebDriver module in the suite configuration file.

                                                                                                                                                            As an example here is an acceptance suite configuration file setting two custom headers, X_WPBROWSER_REQUEST and X_TEST_REQUEST, on each request sent by the WPWebDriver module:

                                                                                                                                                            actor: AcceptanceTester\nmodules:\n    enabled:\n        - WPDb\n        - WPBrowser\n        - \\Helper\\Acceptance\n    config:\n        WPDb:\n            dsn: 'mysql:host=localhost;dbname=tests'\n            user: 'root'\n            password: 'root'\n            dump: 'tests/_data/dump.sql'\n            populate: true\n            cleanup: true\n            waitlock: 10\n            url: 'http://wp.test'\n            urlReplacement: true\n            tablePrefix: 'wp_'\n        WPBrowser:\n            url: 'http://wp.test'\n            adminUsername: 'admin'\n            adminPassword: 'admin'\n            adminPath: '/wp-admin'\n            headers:\n                X_WPBROWSER_REQUEST: 1\n                X_TEST_REQUEST: 1\n

                                                                                                                                                            The two headers are sent on each HTTP request type, not just on GET type requests.

                                                                                                                                                            "},{"location":"v3/tutorials/automatically-change-db-in-tests/#using-a-different-database-to-handle-test-requests","title":"Using a different database to handle test requests","text":"

                                                                                                                                                            Now that each request made by the WPWebDriver module contains those two headers, it's time for WordPress to check those and change the database to use accordingly.

                                                                                                                                                            The database to use is set by the DB_NAME constant that is, in turn, set in the wp-config.php file. Different setups could involve more complex configurations for the wp-config.php file but, for the sake of simplicity, I assume the default WordPress wp-config.php file structure. In the example below, the default database name is wordpress, while the name of the test database is tests.

                                                                                                                                                            - define( 'DB_NAME', 'wordpress' );\n+ if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {\n+     define( 'DB_NAME', 'tests' );\n+ } else {\n+     define( 'DB_NAME', 'wordpress' );\n+ }\n

                                                                                                                                                            The diff shows the replacement done in the WordPress installation wp-config.php file.

                                                                                                                                                            For copy-and-paste pleasure, replace the line starting with:

                                                                                                                                                            define( 'DB_NAME', 'default_db_name' );\n

                                                                                                                                                            With this snippet:

                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {\n      define( 'DB_NAME', 'test_db_name' );\n} else {\n      define( 'DB_NAME', 'default_db_name' );\n}\n

                                                                                                                                                            Where default_db_name is the name of the database your test WordPress installation normally uses.

                                                                                                                                                            Happy, and safer, testing.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/","title":"Setting up wp-browser on Local by Flywheel to test a plugin","text":"

                                                                                                                                                            This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#setting-up-wp-browser-with-local-by-flywheel-to-test-a-plugin","title":"Setting up wp-browser with Local by Flywheel to test a plugin","text":"

                                                                                                                                                            Note: the original version of this guide used, on Mac, the version of Local by Flywheel based on VirtualBox and Docker containers. That version has been replaced by a new one that will not use any virtualization layer. The UI is almost the same but, for back-compatibility purposes, I've not removed the references to the previous version; I have, instead, pointed out where the set up values and procedures might differ due to the changes.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#requirements","title":"Requirements","text":"
                                                                                                                                                            • A Mac or Windows machine
                                                                                                                                                            • A working installation of Local By Flywheel.
                                                                                                                                                            • You should be able to create sites and visit them from your browser without issues.
                                                                                                                                                            • Composer installed and working on your terminal PATH, you should be able to run composer --version at the terminal and see the version correctly.
                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#install-local-by-flywheel","title":"Install Local by Flywheel","text":"

                                                                                                                                                            This walk-through starts after Local by Flywheel has been installed and is correctly running on your machine; you can download Local from the site and follow the installation instructions.

                                                                                                                                                            In the context of this guide I'm assuming the sites directory is ~/Local Sites, the default \"Sites Path\" in Local preferences.

                                                                                                                                                            If your document root lies elsewhere, replace the ~/Local Sites path with the actual directory in each command.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#creating-the-databases-and-installing-wordpress","title":"Creating the databases and installing WordPress","text":"

                                                                                                                                                            Using Local UI create a new site:

                                                                                                                                                            • The site name is myplugin.
                                                                                                                                                            • The site administrator user name is admin.
                                                                                                                                                            • The site administrator password is password.

                                                                                                                                                            Once Local provisioned and installed the new site, open the \"Database\" administration tab and, depending on your OS, start a database administration UI or website. In the image below I'm using Adminer:

                                                                                                                                                            Create a database called tests:

                                                                                                                                                            Make sure you can visit the WordPress installation at http://myplugin.local and that you can correctly access the administration area at http://myplugin.local/wp-admin.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#scaffolding-the-project-folder","title":"Scaffolding the project folder","text":"

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins. Create the main plugin file in the WordPress installation plugins directory, in the ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin/my-plugin.php file:

                                                                                                                                                            <?php\n/**\n * Plugin Name: My plugin\n */ \n

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the WordPress installation at http://myplugin.local/wp-admin/plugins.php.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#installing-wp-browser","title":"Installing wp-browser","text":"

                                                                                                                                                            Open a terminal window and navigate to the plugin directory and initialize the Composer project:

                                                                                                                                                            cd ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin\ncomposer init\n

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. Here is the composer.json file generated by the above answers:

                                                                                                                                                            {\n    \"name\": \"local/my-plugin\",\n    \"type\": \"wordpress-plugin\",\n    \"require\": {}\n}\n

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            composer require --dev lucatume/wp-browser\n

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder. To check Codeception is correctly installed run this command:

                                                                                                                                                            vendor/bin/codecept --version\n

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#setting-up-wp-browser","title":"Setting up wp-browser","text":"

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and \"WordPress unit\" tests.
                                                                                                                                                            • How to connect to the WordPress site \"normal\" database: this is the database that stores the data of the site I would see when visiting the local installation URL at http://myplugin.local.
                                                                                                                                                            • How to connect to the database dedicated to the integration and \"WordPress unit\" tests: this database will be used to install WordPress during integration and \"WordPress unit\" tests.

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that your first step should be to backup the site database.

                                                                                                                                                            You can create a backup of the current site database contents using whatever tool the version of Local you're using provides. In this example I'm using Adminer:

                                                                                                                                                            At any moment you can re-import the site database dump using, again, phpMyAdmin, under the \"Import\" tab:

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#bootstrapping-and-configuring-wp-browser","title":"Bootstrapping and configuring wp-browser","text":"

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            cd ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin\nvendor/bin/codecept init wpbrowser\n

                                                                                                                                                            The initialization guide will ask a number of questions.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#windows-configuration","title":"Windows configuration","text":"

                                                                                                                                                            In the screenshots below are the answers I used to configure wp-browser on Windows.

                                                                                                                                                            Note that I've set up the database host using the values provided by Local UI, yours might differ depending on the version of Local you're using:

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • What is the path of the WordPress root directory? ~/Local Sites/myplugin/app/public
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • What is the host of the test database used by the test site? localhost:10003
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost:10003
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • What is the URL the test site? http://myplugin.local
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@myplugin.local
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#mac-configuration","title":"Mac configuration","text":"

                                                                                                                                                            In the screenshots below are the answers I used to configure wp-browser on Mac.

                                                                                                                                                            Note that I've set up the database host using the values provided by Local UI, yours might differ.

                                                                                                                                                            This screenshot is from the previous version of Local, the one based on VirtualBox and Docker:

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • What is the path of the WordPress root directory? ~/Local Sites/myplugin/app/public
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • What is the host of the test database used by the test site? /Users/lucatume/Library/Application Support/Local/run/FjKWfVMGd/mysql/mysqld.sock ( or 192.168.95.100:4055 on an older version of Local)
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • What is the host of the test database WPLoader should use? /Users/lucatume/Library/Application Support/Local/run/FjKWfVMGd/mysql/mysqld.sock (or 192.168.95.100:4055 on an older version of Local)
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • What is the URL the test site? http://myplugin.local
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@myplugin.local
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#setting-up-the-starting-database-fixture","title":"Setting up the starting database fixture","text":"

                                                                                                                                                            A \"fixture\", in testing terms, is a minimal, starting environment shared by all tests. In BDD it's the Background any scenario will share. In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.

                                                                                                                                                            You should set up this fixture \"manually\", using the site administration UI at http://myplugin.local/wp-admin.

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            When you're done setting up the initial database fixture, export it using the \"Export\" tab of your database tool of choice, and move the file to the ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin/tests/_data/dump.sql directory.

                                                                                                                                                            There is one last step left to complete the setup.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#using-the-tests-database-in-acceptance-and-functional-tests","title":"Using the tests database in acceptance and functional tests","text":"

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the ~/Local Sites/myplugin/app/public/wp-config.php file, the DB_NAME constant is set to local.

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            • If the request is a normal one, use the local database.
                                                                                                                                                            • If the request comes from a test, use the tests database.

                                                                                                                                                            In your IDE/text-editor of choice edit the ~/Local Sites/myplugin/app/public/wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            - define( 'DB_NAME', 'local' );\n+ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { \n+    define( 'DB_NAME', 'tests' );\n+ } else {\n+    define( 'DB_NAME', 'local' );\n+ }\n

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {\n        define( 'DB_NAME', 'tests' );\n} else {\n        define( 'DB_NAME', 'local' );\n}\n

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            headers:\n    X_TEST_REQUEST: 1\n    X_WPBROWSER_REQUEST: 1\n

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers. Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            "},{"location":"v3/tutorials/local-flywheel-setup/#sanity-check","title":"Sanity check","text":"

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works. Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            cd ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin \nvendor/bin/codecept run acceptance\nvendor/bin/codecept run functional\nvendor/bin/codecept run wpunit\nvendor/bin/codecept run unit\n

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept to see a list of the available commands.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/","title":"Setting up wp-browser on MAMP for Mac to test a plugin","text":"

                                                                                                                                                            This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#setting-up-wp-browser-with-mamp-on-mac-to-test-a-plugin","title":"Setting up wp-browser with MAMP on Mac to test a plugin","text":""},{"location":"v3/tutorials/mamp-mac-setup/#requirements","title":"Requirements","text":"
                                                                                                                                                            • A Mac machine
                                                                                                                                                            • A working installation of MAMP.
                                                                                                                                                            • You should be able to create sites and visit them from your browser without issues.
                                                                                                                                                            • Composer installed and working on your terminal PATH, you should be able to run composer --version at the terminal and see the version correctly.

                                                                                                                                                            The version of MAMP used in this tutorial is the free, non PRO, one. MAMP PRO provides more features, but the setup instructions should remain valid.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#install-and-configure-mamp","title":"Install and configure MAMP","text":"

                                                                                                                                                            This walk-through starts after MAMP has been installed and is correctly running on the host machine; you can download MAMP from the site and follow the installation instructions. In the context of this guide I'm assuming the \"Document Root\" directory is the default one, in the /Applications/MAMP/htdocs directory. If your document root lies elsewhere, replace the /Applications/MAMP/htdocs path with the actual directory in each command.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#creating-the-databases-and-installing-wordpress","title":"Creating the databases and installing WordPress","text":"

                                                                                                                                                            Go to the http://localhost/phpMyAdmin/ page and create two new databases:

                                                                                                                                                            • wordpress is the database you will use for WordPress
                                                                                                                                                            • tests is the database you will use for the tests

                                                                                                                                                            Unzip the the WordPress files into the /Applications/MAMP/htdocs and head over to http://localhost to install WordPress.

                                                                                                                                                            The database credentials for the installation are:

                                                                                                                                                            • Database name: wordpress
                                                                                                                                                            • Database user: root
                                                                                                                                                            • Database password: root
                                                                                                                                                            • Database host: localhost

                                                                                                                                                            Use admin as administrator user name and password as password for the administrator user.

                                                                                                                                                            Make sure you can visit the WordPress installation at http://localhost and that you can correctly access the administration area at http://localhost/wp-admin.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#scaffolding-the-project-folder","title":"Scaffolding the project folder","text":"

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins. Create the main plugin file in the WordPress installation plugins directory, in the /Applications/MAMP/htdocs/wp-content/plugins/my-plugin/my-plugin.php file:

                                                                                                                                                            <?php\n/**\n * Plugin Name: My plugin\n */ \n

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the WordPress installation at http://localhost/wp-admin/plugins.php.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#installing-wp-browser","title":"Installing wp-browser","text":"

                                                                                                                                                            Open a terminal window and navigate to the plugin directory and initialize the Composer project:

                                                                                                                                                            cd /Applications/MAMP/htdocs/wp-content/plugins/my-plugin\ncomposer init\n

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. Here is the composer.json file generated by the above answers:

                                                                                                                                                            {\n    \"name\": \"mamp/my-plugin\",\n    \"type\": \"wordpress-plugin\",\n    \"require\": {}\n}\n

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            composer require --dev lucatume/wp-browser\n

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder. To check Codeception is correctly installed run this command:

                                                                                                                                                            vendor/bin/codecept --version\n

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#setting-up-wp-browser","title":"Setting up wp-browser","text":"

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and \"WordPress unit\" tests.
                                                                                                                                                            • How to connect to the WordPress site \"normal\" database: this is the database that stores the data of the site I would see when visiting the local installation URL at http://localhost.
                                                                                                                                                            • How to connect to the database dedicated to the integration and \"WordPress unit\" tests: this database will be used to install WordPress during integration and \"WordPress unit\" tests.

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that your first step should be to backup the site database.

                                                                                                                                                            You can create a backup of the current site database contents using phpMyAdmin, at http://localhost/phpMyAdmin/, under the \"Export\" tab:

                                                                                                                                                            At any moment you can re-import the site database dump using, again, phpMyAdmin, under the \"Import\" tab:

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#bootstrapping-and-configuring-wp-browser","title":"Bootstrapping and configuring wp-browser","text":"

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            cd /Applications/MAMP/htdocs/wp-content/plugins/my-plugin\nvendor/bin/codecept init wpbrowser\n

                                                                                                                                                            The initialization guide will ask a number of questions. In the screenshots below are the answers I used to configure wp-browser.

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • What is the path of the WordPress root directory? /Applications/MAMP/htdocs
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • What is the host of the test database used by the test site? localhost
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • What is the URL the test site? http://localhost
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@wp.test
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#setting-up-the-starting-database-fixture","title":"Setting up the starting database fixture","text":"

                                                                                                                                                            A \"fixture\", in testing terms, is a minimal, starting environment shared by all tests. In BDD it's the Background any scenario will share. In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.

                                                                                                                                                            You should set up this fixture \"manually\", using the site administration UI at http://localhost/wp-admin.

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            When you're done setting up the initial database fixture, export it using the \"Export\" tab of phpMyAdmin, at http://localhost/phpMyAdmin/ and move the file to the /Applications/MAMP/htdocs/wp-content/plugins/my-plugin/tests/_data/dump.sql directory.

                                                                                                                                                            There is one last step left to complete the setup.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#using-the-tests-database-in-acceptance-and-functional-tests","title":"Using the tests database in acceptance and functional tests","text":"

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the /Applications/MAMP/htdocs/wp-config.php file, the DB_NAME constant is set to wordpress.

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            • If the request is a normal one, use the wordpress database.
                                                                                                                                                            • If the request comes from a test, use the tests database.

                                                                                                                                                            In your IDE/text-editor of choice edit the /Applications/MAMP/htdocs/wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            - define( 'DB_NAME', 'wordpress' );\n+ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { \n+    define( 'DB_NAME', 'tests' );\n+ } else {\n+    define( 'DB_NAME', 'wordpress' );\n+ }\n

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {\n        define( 'DB_NAME', 'tests' );\n} else {\n        define( 'DB_NAME', 'wordpress' );\n}\n

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            headers:\n    X_TEST_REQUEST: 1\n    X_WPBROWSER_REQUEST: 1\n

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers. Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            "},{"location":"v3/tutorials/mamp-mac-setup/#sanity-check","title":"Sanity check","text":"

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works. Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            cd /Applications/MAMP/htdocs/wp-content/plugins/my-plugin \nvendor/bin/codecept run acceptance\nvendor/bin/codecept run functional\nvendor/bin/codecept run wpunit\nvendor/bin/codecept run unit\n

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept to see a list of the available commands.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/","title":"Setting up wp-browser on VVV to test a plugin","text":"

                                                                                                                                                            This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#setting-up-wp-browser-on-vvv-to-test-a-plugin","title":"Setting up wp-browser on VVV to test a plugin","text":""},{"location":"v3/tutorials/vvv-setup/#requirements","title":"Requirements","text":"
                                                                                                                                                            • A Windows, Linux or Mac machine (I'll call this the \"host machine\" or just \"host\").
                                                                                                                                                            • A working installation of VVV; you should be able to navigate to VVV root directory, run the vagrant up command, and have VVV up and running.
                                                                                                                                                            • On the VVV installation you should be able to visit the two default sites URLs without issues; the two default sites addresses are:
                                                                                                                                                              • http://one.wordpress.test
                                                                                                                                                              • http://two.wordpress.test
                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#why-vvv","title":"Why VVV?","text":"

                                                                                                                                                            The VVV project provides a \"a Vagrant configuration for developing with WordPress\" and is an excellent, no-frills, starting point to develop WordPress projects (themes, plugins and whole sites. Based on Vagrant and Virtual Box, VVV removes the differences between systems by providing a uniform, Ubuntu Linux based, virtual machine that will bahave the same on Windows, Linux and Mac. Configuring it to run WordPress tests is easy: let's get started.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#check-vvv-works-correctly","title":"Check VVV works correctly","text":"

                                                                                                                                                            This walk-through starts after VVV has been installed and is running on the host machine; the installation guide is clear and simple to follow and I'm not duplicating it here. In the context of this guide I'm assuming VVV lives in the ~/Repos/VVV directory, that we are working on the my-plugin project and that the plugin is being developed in the default (wordpress-one) WordPress installation provided by the box. If your VVV installation lies elsewhere, replace the ~/Repos/VVV with the actual directory in each command.

                                                                                                                                                            After completing the installation of VVV navigate to VVV root folder and run the vagrant up command:

                                                                                                                                                            cd ~/Repos/VVV\nvagrant up\n

                                                                                                                                                            After the automatic bootstrap and initialization process completed, VVV makes two WordPress sites available:

                                                                                                                                                            • http://one.wordpress.test/ is the first default site address.
                                                                                                                                                            • http://two.wordpress.test/ is the second default site address.
                                                                                                                                                            • http://vvv.test/ is VVV dashboard address.

                                                                                                                                                            You should be able to reach each one of the URLs above without issues, should this not be the case something during VVV setup did not go according to the plan and you should fix it before moving on.

                                                                                                                                                            If the sanity check above is complete it's time to move to the following part specific to Codeception and wp-browser setup.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#in-and-out-host-and-guest","title":"In and out, host and guest","text":"

                                                                                                                                                            The Vagrant box provided by VVV goes beyond a simple MySQL, PHP and Ngnix server stack and provides a complete WordPress development environment; tools like Composer, [grunt-cli][4992-0003], and [wp-cli][4992-0006] are ready to use.

                                                                                                                                                            This allows the entire development, when it comes to the CLI tools, to happen in the virtual machine and not outside of it.

                                                                                                                                                            \"Inside the virtual machine\" means the first CLI instruction to run from the ~/Repos/VVV folder (assuming that is the folder where VVV was installed) is this:

                                                                                                                                                            cd ~/Repos/VVV\nvagrant ssh\n

                                                                                                                                                            This will connect, via SSH, to the virtual machine as the vagrant user. To exit from the SSH session inside the box, just type exit and return.

                                                                                                                                                            Note: any further instruction I'm showing here, beside the code editing that will happen in a dedicated PHP IDE like [PHPStorm][4992-0004] or [Sublime Text][4992-0005] on the host machine, will happen \"inside the virtual machine\".

                                                                                                                                                            When I say \"host machine\" I mean your laptop, desktop or whatever computer you're working on; when I say \"guest machine\" I mean VVV virtual machine; this is usually the case for any virtual-ish setup (Vagrant, Docker and the like).

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#scaffolding-the-project-folder","title":"Scaffolding the project folder","text":"

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins. Create the main plugin file in the http://one.wordpress.test installation plugins directory, in the ~/Repos/VVV/www/wordpress-one/public_html/wp-content/plugins/my-plugin/my-plugin.php file:

                                                                                                                                                            <?php\n/**\n * Plugin Name: My plugin\n */ \n

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the VVV default WordPress installation at http://one.wordpress.test/wp-admin/plugins.php.

                                                                                                                                                            By default, VVV administrator user name is admin and password is password.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#installing-wp-browser","title":"Installing wp-browser","text":"

                                                                                                                                                            Since Composer is provided from VVV, installing wp-browser requires entering the virtual machine (if you did not already):

                                                                                                                                                            cd ~/Repos/VVV\nvagrant ssh\n

                                                                                                                                                            Once inside navigate to the plugins folder. The path is now relative to VVV filesystem structure so it won't be the same as the one used above that was, instead, in the context of the \"host machine\":

                                                                                                                                                            cd /srv/www/wordpress-one/public_html/wp-content/plugins/my-plugin \ncomposer init\n

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. Here is the composer.json file generated by the above answers:

                                                                                                                                                            {\n    \"name\": \"vagrant/my-plugin\",\n    \"type\": \"wordpress-plugin\",\n    \"require\": {}\n}\n

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            composer require --dev lucatume/wp-browser\n

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder. To check Codeception is correctly installed run this command:

                                                                                                                                                            vendor/bin/codecept --version\n

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#setting-up-wp-browser","title":"Setting up wp-browser","text":"

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and \"WordPress unit\" tests.
                                                                                                                                                            • How to connect to the WordPress site \"normal\" database: this is the database that stores the data of the site I would see when visiting the local installation URL (http://one.wordpress.test in the case of the VVV default installation).
                                                                                                                                                            • How to connect to the database dedicated to the integration and \"WordPress unit\" tests: this database will be used to install WordPress during integration and \"WordPress unit\" tests.

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that if I am using VVV for my day to day WordPress development my first step should be to backup the site database.

                                                                                                                                                            You can create a backup of the current site database contents using wp-cli from within the virtual machine:

                                                                                                                                                            cd /srv/www/wordpress-one/public_html\nwp db export wordpress-one-backup.sql\n

                                                                                                                                                            At any moment you can re-import the site database dump using this command, the site database will be reset to the state it was when you created the database dump:

                                                                                                                                                            cd /srv/www/wordpress-one/public_html\nwp db import wordpress-one-backup.sql\n

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#creating-the-database-dedicated-to-the-tests","title":"Creating the database dedicated to the tests","text":"

                                                                                                                                                            wp-browser will use the databases it works on in a destructive way: between tests the data will be lost.

                                                                                                                                                            After the backup you should have done in the previous step, the next step is creating a database dedicated to the test.

                                                                                                                                                            At the VVV box command line run:

                                                                                                                                                            mysql -u root -p -e \"CREATE DATABASE if not exists tests\"\nmysql -u root -p -e \"GRANT ALL PRIVILEGES ON tests.* TO 'wp'@'localhost';\"\n

                                                                                                                                                            When prompted for the password enter root. The first command creates the tests database, if it does not exist; the second command grants the wp user all privileges on it.

                                                                                                                                                            In VVV the root database user name is root and the password is root.

                                                                                                                                                            Check the database was correctly created running this command:

                                                                                                                                                            mysql -u root -p -e \"SHOW DATABASES\"\n

                                                                                                                                                            The tests database should be present in the list.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#bootstrapping-and-configuring-wp-browser","title":"Bootstrapping and configuring wp-browser","text":"

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            cd /srv/www/wordpress-one/public_html/wp-content/plugins/my-plugin\nvendor/bin/codecept init wpbrowser\n

                                                                                                                                                            The initialization guide will ask a number of questions. In the screenshots below are the answers I used to configure wp-browser.

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • What is the path of the WordPress root directory? /srv/www/wordpress-one/public_html
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • What is the host of the test database used by the test site? localhost
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • What is the URL the test site? http://one.wordpress.test
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@one.wordpress.test
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#setting-up-the-starting-database-fixture","title":"Setting up the starting database fixture","text":"

                                                                                                                                                            A \"fixture\", in testing terms, is a minimal, starting environment shared by all tests. In BDD it's the Background any scenario will share. In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.

                                                                                                                                                            You can set up this fixture \"manually\", using the site administration UI at http://one.wordpress.test/wp-admin, or use wp-cli and save precious time.

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            As it's been the case so far, I'm running the following command from within the VVV box (use vagrant ssh to log in):

                                                                                                                                                            cd /srv/www/wordpress-one/public_html\nwp site empty --yes --uploads\nwp plugin deactivate --all\nwp plugin activate my-plugin\nwp db export wp-content/plugins/my-plugin/tests/_data/dump.sql\n

                                                                                                                                                            The initial database fixture has been created, now there's one last step to complete.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#using-the-tests-database-in-acceptance-and-functional-tests","title":"Using the tests database in acceptance and functional tests","text":"

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the /srv/www/wordpress-one/public_html/wp-config.php file, the DB_NAME constant is set to wordpress-one.

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            • If the request is a normal one, use the wordpress-one database.
                                                                                                                                                            • If the request comes from a test, use the tests database.

                                                                                                                                                            In your IDE/text-editor of choice edit the ~/Repos/VVV/www/wordpress-one/public_html/wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            - define( 'DB_NAME', 'wordpress-one' );\n+ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { \n+    define( 'DB_NAME', 'tests' );\n+ } else {\n+    define( 'DB_NAME', 'wordpress-one' );\n+ }\n

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {\n        define( 'DB_NAME', 'tests' );\n} else {\n        define( 'DB_NAME', 'wordpress-one' );\n}\n

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            headers:\n    X_TEST_REQUEST: 1\n    X_WPBROWSER_REQUEST: 1\n

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers. Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            "},{"location":"v3/tutorials/vvv-setup/#sanity-check","title":"Sanity check","text":"

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works. Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            cd /srv/www/wordpress-one/public_html/wp-content/plugins/my-plugin \nvendor/bin/codecept run acceptance\nvendor/bin/codecept run functional\nvendor/bin/codecept run wpunit\nvendor/bin/codecept run unit\n

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept to see a list of the available commands.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/","title":"Setting up wp-browser on WAMP for Windows to test a plugin","text":"

                                                                                                                                                            This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#setting-up-wp-browser-with-wamp-on-windows-to-test-a-plugin","title":"Setting up wp-browser with WAMP on Windows to test a plugin","text":""},{"location":"v3/tutorials/wamp-setup/#requirements","title":"Requirements","text":"
                                                                                                                                                            • A Windows machine
                                                                                                                                                            • A working installation of WAMP.
                                                                                                                                                            • You should be able to create sites and visit them from your browser without issues.
                                                                                                                                                            • Composer installed and working on your terminal PATH, you should be able to run composer --version at the terminal and see the version correctly.
                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#install-and-configure-wamp","title":"Install and configure WAMP","text":"

                                                                                                                                                            This walk-through starts after WAMP has been installed and is correctly running on the host machine; you can download WAMP from the site and follow the installation instructions. In the context of this guide I'm installing the test WordPress installation in the C:\\wamp64\\www\\wp directory. If your installation lies elsewhere, replace the C:\\wamp64\\www\\wp path with the actual directory in each command.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#creating-the-databases-and-installing-wordpress","title":"Creating the databases and installing WordPress","text":"

                                                                                                                                                            Go to the http://localhost/phpmyadmin/index.php page and create two new databases:

                                                                                                                                                            • wordpress is the database you will use for WordPress
                                                                                                                                                            • tests is the database you will use for the tests

                                                                                                                                                            The default database user is root, the default password is empty.

                                                                                                                                                            Unzip the the WordPress files into the C:\\wamp64\\www\\wp and head over to http://localhost/wp to install WordPress. The database credentials for the installation are:

                                                                                                                                                            • Database name: wordpress
                                                                                                                                                            • Database user: root
                                                                                                                                                            • Database password is empty
                                                                                                                                                            • Database host: localhost

                                                                                                                                                            Use admin as administrator user name and password as password for the administrator user.

                                                                                                                                                            Make sure you can visit the WordPress installation at http://localhost/wp and that you can correctly access the administration area at http://localhost/wp/wp-admin.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#scaffolding-the-project-folder","title":"Scaffolding the project folder","text":"

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins. Create the main plugin file in the WordPress installation plugins directory, in the C:\\wamp64\\www\\wp\\wp-content\\plugins\\my-plugin\\my-plugin.php file:

                                                                                                                                                            <?php\n/**\n * Plugin Name: My plugin\n */ \n

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the WordPress installation at http://localhost/wp/wp-admin/plugins.php.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#installing-wp-browser","title":"Installing wp-browser","text":"

                                                                                                                                                            Open a terminal window and navigate to the plugin directory and initialize the Composer project. I'm using Cmder as terminal emulator on Windows, but you can use the default one.

                                                                                                                                                            cd C:\\wamp64\\www\\wp\\wp-content\\plugins\\my-plugin\ncomposer init\n

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. Here is the composer.json file generated by the above answers:

                                                                                                                                                            {\n    \"name\": \"wamp/my-plugin\",\n    \"type\": \"wordpress-plugin\",\n    \"require\": {}\n}\n

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            composer require --dev lucatume/wp-browser\n

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder. To check Codeception is correctly installed run this command:

                                                                                                                                                            vendor\\bin\\codecept.bat --version\n

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#setting-up-wp-browser","title":"Setting up wp-browser","text":"

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and \"WordPress unit\" tests.
                                                                                                                                                            • How to connect to the WordPress site \"normal\" database: this is the database that stores the data of the site I would see when visiting the local installation URL at http://localhost/wp.
                                                                                                                                                            • How to connect to the database dedicated to the integration and \"WordPress unit\" tests: this database will be used to install WordPress during integration and \"WordPress unit\" tests.

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that your first step should be to backup the site database.

                                                                                                                                                            You can create a backup of the current site database contents using phpMyAdmin, at http://localhost/phpmyadmin/, under the \"Export\" tab:

                                                                                                                                                            At any moment you can re-import the site database dump using, again, phpMyAdmin, under the \"Import\" tab:

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#bootstrapping-and-configuring-wp-browser","title":"Bootstrapping and configuring wp-browser","text":"

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            cd C:\\wamp64\\www\\wp\\wp-content\\plugins\\my-plugin\nvendor/bin/codecept.bat init wpbrowser\n

                                                                                                                                                            The initialization guide will ask a number of questions. In the screenshots below are the answers I used to configure wp-browser.

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • What is the path of the WordPress root directory? C:/wamp64/www/wp
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • What is the host of the test database used by the test site? localhost
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • What is the password of the test database used by the test site? ``
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • What is the password of the test database WPLoader should use? ``
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • What is the URL the test site? http://localhost/wp
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@wp.test
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#setting-up-the-starting-database-fixture","title":"Setting up the starting database fixture","text":"

                                                                                                                                                            A \"fixture\", in testing terms, is a minimal, starting environment shared by all tests. In BDD it's the Background any scenario will share. In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.

                                                                                                                                                            You should set up this fixture \"manually\", using the site administration UI at http://localhost/wp/wp-admin.

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            When you're done setting up the initial database fixture, export it using the \"Export\" tab of phpMyAdmin, at http://localhost/phpmyadmin/ and move the file to the C:\\wamp64\\www\\wp\\wp-content\\plugins\\my-plugin\\tests\\_data\\dump.sql directory.

                                                                                                                                                            There is one last step left to complete the setup.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#using-the-tests-database-in-acceptance-and-functional-tests","title":"Using the tests database in acceptance and functional tests","text":"

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the C:\\wamp64\\www\\wp\\wp-config.php file, the DB_NAME constant is set to wordpress.

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            • If the request is a normal one, use the wordpress database.
                                                                                                                                                            • If the request comes from a test, use the tests database.

                                                                                                                                                            In your IDE/text-editor of choice edit the C:\\wamp64\\www\\wp\\wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            - define( 'DB_NAME', 'wordpress' );\n+ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { \n+    define( 'DB_NAME', 'tests' );\n+ } else {\n+    define( 'DB_NAME', 'wordpress' );\n+ }\n

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {\n        define( 'DB_NAME', 'tests' );\n} else {\n        define( 'DB_NAME', 'wordpress' );\n}\n

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            headers:\n    X_TEST_REQUEST: 1\n    X_WPBROWSER_REQUEST: 1\n

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers. Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            "},{"location":"v3/tutorials/wamp-setup/#sanity-check","title":"Sanity check","text":"

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works. Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            cd C:\\wamp64\\www\\wp\\wp-content\\plugins\\my-plugin \nvendor/bin/codecept run acceptance\nvendor/bin/codecept run functional\nvendor/bin/codecept run wpunit\nvendor/bin/codecept run unit\n

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept.bat to see a list of the available commands.

                                                                                                                                                            "}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..43f27de78 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,253 @@ + + + + https://wpbrowser.wptestkit.dev/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/DispatcherAPI/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/commands/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/custom-configuration/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/default-configuration/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/extensions/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/migration/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/troubleshooting/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/extensions/BuiltInServerController/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/extensions/ChromeDriverController/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/extensions/DockerComposeController/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/extensions/EventDispatcherBridge/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/extensions/IsolationSupport/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/extensions/Symlinker/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/AirplaneMode/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/WPBrowser/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/WPCLI/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/WPDb/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/WPFilesystem/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/WPLoader/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/WPQueries/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/modules/WPWebDriver/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/traits/UopzFunctions/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/codeception-4-support/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/codeception-phpunit-and-wpbrowser/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/commands/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/configuration/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/events-api/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/extensions/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/faq/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/installation/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/levels-of-testing/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/requirements/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/setting-up-minimum-wordpress-installation/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/advanced/run-in-separate-process/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/migration/from-version-2-to-version-3/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WPBrowser/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WPCLI/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WPDb/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WPFilesystem/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WPLoader/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WPQueries/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WPWebDriver/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/modules/WordPress/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/tutorials/automatically-change-db-in-tests/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/tutorials/local-flywheel-setup/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/tutorials/mamp-mac-setup/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/tutorials/vvv-setup/ + 2024-06-18 + daily + + + https://wpbrowser.wptestkit.dev/v3/tutorials/wamp-setup/ + 2024-06-18 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 000000000..406793c79 Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/traits/UopzFunctions/index.html b/traits/UopzFunctions/index.html new file mode 100644 index 000000000..28c21ef37 --- /dev/null +++ b/traits/UopzFunctions/index.html @@ -0,0 +1,4848 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UopzFunctions trait - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            UopzFunctions trait

                                                                                                                                                            + +

                                                                                                                                                            This trait provides a set of methods to manipulate functions, methods and class attributes using the uopz PHP +extension.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Warning

                                                                                                                                                            +

                                                                                                                                                            This test trait requires the uopz PHP extension.

                                                                                                                                                            +

                                                                                                                                                            See the Installing the extension locally section of this page for more information about how to do that.
                                                                                                                                                            +If you need to install the extension in a CI environment, see the Installing the extension in CI section of this page.

                                                                                                                                                            +

                                                                                                                                                            If the uopz extension is not installed, test methods using methods from the UopzFunctions trait will be marked as skipped.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Why require an extension?

                                                                                                                                                            +

                                                                                                                                                            Why use a PHP extension instead of a user-land solution, i.e. a PHP library that does not require installing an +extension?

                                                                                                                                                            +

                                                                                                                                                            I've written such a solution myself, function-mocker, but have grown frustrated with its limitations, and the +limitation of other similar solutions.

                                                                                                                                                            +

                                                                                                                                                            All user-land, monkey-patching, pure PHP solutions rely on stream-wrapping.
                                                                                                                                                            +This is a very powerful feature that this project uses for some of its functionality, but it has a drawbacks when used +extensively for monkey-patching functions and methods:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • the files patch must be included after the library loaded
                                                                                                                                                            • +
                                                                                                                                                            • the files have to patched, or patched and cached, on each run
                                                                                                                                                            • +
                                                                                                                                                            • there are some random and difficult to track issues introduced by how function and method patching works; e.g. + functions manipulating values by reference will not work as expected
                                                                                                                                                            • +
                                                                                                                                                            • some constants like __METHOD__ and __FUNCTION__ will not work as expected in the patched files
                                                                                                                                                            • +
                                                                                                                                                            • monkey-patching code will be "inserted" in the function stack, lengthening the stack trace and making it very + difficult to debug
                                                                                                                                                            • +
                                                                                                                                                            • all this processing together with XDebug spells doom for the performance of the test suite
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The uopz extension is a solid and fast solution that has been created and maintained by people that know PHP +internals and the PHP language very well that has none of the drawbacks of the above-mentioned solutions.

                                                                                                                                                            +

                                                                                                                                                            It is just a better tool for the job.

                                                                                                                                                            +

                                                                                                                                                            Installing the extension locally

                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Locate your php.ini file: +
                                                                                                                                                              php --ini
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • Download the latest DLL stable version of the extension from the releases page. You'll likely need the NTS x64 version.
                                                                                                                                                            • +
                                                                                                                                                            • Unzip the file and copy the php_uopz.dll file to the ext folder of your PHP installation. If your php.ini file is located at C:\tools\php81\php.ini, the extensions directory will be located at C:\tools\php81\ext.
                                                                                                                                                            • +
                                                                                                                                                            • Edit your php.ini file and add the following line to enable and configure the extension: +
                                                                                                                                                              extension=uopz
                                                                                                                                                              +uopz.exit=1
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • Make sure the extension is correctly installed by running php -m and making sure the uopz extension appears in the list of extensions.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            You can find more information about installing PHP extensions on Windows in the PHP manual and in the uopz extension install guide.

                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Use the pecl command to install the extension: +
                                                                                                                                                              pecl install uopz
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • Configure the extension to ensure it will allow exit and die calls to terminate the script execution.
                                                                                                                                                              + Add the following line to either the main PHP configuration file (php.ini), or a dedicated configuration file: +
                                                                                                                                                              uopz.exit=1
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • Make sure the extension is correctly installed by running php -m and making sure the uopz extension appears in the list of extensions.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Alternatively, you can build the extension from source as detailed in the uopz extension install guide.

                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Use the pecl command to install the extension: +
                                                                                                                                                              pecl install uopz
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • Configure the extension to ensure it will allow exit and die calls to terminate the script execution.
                                                                                                                                                              + Add the following line to either the main PHP configuration file (php.ini), or a dedicated configuration file: +
                                                                                                                                                              uopz.exit=1
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • Make sure the extension is correctly installed by running php -m and making sure the uopz extension appears in the list of extensions.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Alternatively, you can build the extension from source as detailed in the uopz extension install guide.

                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Installing the extension in CI

                                                                                                                                                            +

                                                                                                                                                            Depending on your Continuous Integration (CI) solution of choice, the configuration required to install and set up +the uopz extensions will be different.

                                                                                                                                                            +

                                                                                                                                                            As an example, here is how you can set up the uopz extension in a GitHub Actions job:

                                                                                                                                                            +
                                                                                                                                                            - name: Setup PHP 8.1 with uopz
                                                                                                                                                            +uses: shivammathur/setup-php@v2
                                                                                                                                                            +with:
                                                                                                                                                            +  php-version: 8.1
                                                                                                                                                            +  extensions: uopz
                                                                                                                                                            +  ini-values: uopz.exit=1
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This project uses the very same setup.

                                                                                                                                                            +

                                                                                                                                                            Most CI systems are based on Linux OSes: if you're not using GitHub Actions, you can reference to the +Linux local installation instructions to set up and install the extension for your +CI solution of choice.

                                                                                                                                                            +

                                                                                                                                                            Usage

                                                                                                                                                            +

                                                                                                                                                            Include the UopzFunctions trait in your test class and use the methods provided by the trait to manipulate functions, +methods and class attributes.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\WPTestCase;
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_mock_wp_create_nonce()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setFunctionReturn('wp_create_nonce', 'super-secret-nonce');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('super-secret-nonce', wp_create_nonce('some-action'));
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after +each test.

                                                                                                                                                            +

                                                                                                                                                            You can use the UopzFunctions trait in test cases extending the PHUnit\Framework\TestCase class as well:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use PHPUnit\Framework\TestCase;
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends TestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_mock_my_function()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setFunctionReturn('someFunction', 'mocked-value');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('mocked-value', someFunction());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Methods

                                                                                                                                                            +

                                                                                                                                                            The UopzFunctions trait provides the following methods:

                                                                                                                                                            +

                                                                                                                                                            setFunctionReturn

                                                                                                                                                            +

                                                                                                                                                            setFunctionReturn(string $function, mixed $value, bool $execute = false): void

                                                                                                                                                            +

                                                                                                                                                            Set the return value for the function $function to $value.

                                                                                                                                                            +

                                                                                                                                                            If $value is a closure and $execute is true, then the return value will be the return value of the closure.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_function_return()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setFunctionReturn('wp_generate_nonce', 'super-secret-nonce');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('super-secret-nonce', wp_create_nonce('some-action'));
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If $value is a closure, the original function can be called within the closure to relay the original return value:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_function_return_with_closure()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setFunctionReturn(
                                                                                                                                                            +            'wp_generate_nonce',
                                                                                                                                                            +            fn(string $action) => $action === 'test' ? 'test-nonce' : wp_create_nonce($action),
                                                                                                                                                            +            true
                                                                                                                                                            +        );
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('test-nonce', wp_create_nonce('test'));
                                                                                                                                                            +        $this->assertNotEquals('test-nonce', wp_create_nonce('some-other-action'));
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            unsetFunctionReturn

                                                                                                                                                            +

                                                                                                                                                            unsetFunctionReturn(string $function): void

                                                                                                                                                            +

                                                                                                                                                            Unset the return value for the function $function previously set with setFunctionReturn.

                                                                                                                                                            +

                                                                                                                                                            You do not need to unset the return value for a function that was set with setFunctionReturn +using unsetFunctionReturn explicitly: the trait will take care of cleaning up all the modifications made to the +functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            setMethodReturn

                                                                                                                                                            +

                                                                                                                                                            setMethodReturn(string $class, string $method, mixed $value, bool $execute = false): void

                                                                                                                                                            +

                                                                                                                                                            Sets the return value for the static or instance method $method of the class $class to $value.

                                                                                                                                                            +

                                                                                                                                                            If $value is a closure and $execute is true, then the return value will be the return value of the closure.

                                                                                                                                                            +

                                                                                                                                                            Magic methods like __construct, __destruct, __call and so on cannot be mocked using this method. +See the setClassMock method for more information about how to mock magic class methods.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class SomeLegacyClass {
                                                                                                                                                            +    public static function staticMethod(){
                                                                                                                                                            +        return 'some-static-value';
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function instanceMethod(){
                                                                                                                                                            +        return 'some-instance-value';
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_method_return()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setMethodReturn(SomeLegacyClass::class, 'staticMethod', 'STATIC');
                                                                                                                                                            +        $this->setMethodReturn(SomeLegacyClass::class, 'instanceMethod', 'TEST');
                                                                                                                                                            +
                                                                                                                                                            +        $legacyClass = new SomeLegacyClass();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('STATIC', SomeLegacyClass::staticMethod());
                                                                                                                                                            +        $this->assertEquals('TEST', $legacyClass->instanceMethod());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If $value is a closure, the original static or instance method can be called within the closure, with correctly +bound self and $this context, to relay the original return value:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class SomeLegacyClass {
                                                                                                                                                            +    public static function raiseStaticFlag(bool $flag = false){
                                                                                                                                                            +        return $flag ? 'static-flag-raised' : 'static-flag-lowered';
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function raiseFlag(bool $flag = false){
                                                                                                                                                            +        return $flag ? 'flag-raised' : 'flag-lowered';
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_method_return_with_closure()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setMethodReturn(
                                                                                                                                                            +            SomeLegacyClass::class,
                                                                                                                                                            +            'raiseStaticFlag',
                                                                                                                                                            +            fn(bool $flag) => $flag ? 'STATIC' : self::raiseStaticFlag($flag),
                                                                                                                                                            +            true
                                                                                                                                                            +        );
                                                                                                                                                            +        $this->setMethodReturn(
                                                                                                                                                            +            SomeLegacyClass::class,
                                                                                                                                                            +            'raiseFlag',
                                                                                                                                                            +            fn(bool $flag) => $flag ? 'TEST' : $this->raiseFlag($flag),
                                                                                                                                                            +            true
                                                                                                                                                            +        );
                                                                                                                                                            +
                                                                                                                                                            +        $legacyClass = new SomeLegacyClass();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('STATIC', SomeLegacyClass::raiseStaticFlag(true));
                                                                                                                                                            +        $this->assertEquals('static-flag-lowered', SomeLegacyClass::raiseStaticFlag(false));
                                                                                                                                                            +        $this->assertEquals('TEST', $legacyClass->raiseFlag(true));
                                                                                                                                                            +        $this->assertEquals('flag-lowered', $legacyClass->raiseFlag(false));
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            unsetmethodreturn

                                                                                                                                                            +

                                                                                                                                                            unsetmethodreturn(string $class, string $method): void

                                                                                                                                                            +

                                                                                                                                                            Unset the return value for the static or instance method $method of the class $class previously set +with setMethodReturn.

                                                                                                                                                            +

                                                                                                                                                            You do not need to unset the return value for a method that was set with setMethodReturn +using unsetMethodReturn explicitly: the trait will take care of cleaning up all the modifications made to the +functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            setFunctionHook

                                                                                                                                                            +

                                                                                                                                                            setFunctionHook(string $function, Closure $hook): void

                                                                                                                                                            +

                                                                                                                                                            Execute $hook when entering the function $function.

                                                                                                                                                            +

                                                                                                                                                            Hooks can be set on both internal and user-defined functions.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_hook()
                                                                                                                                                            +    {
                                                                                                                                                            +        $log = [];
                                                                                                                                                            +        $this->setFunctionHook(
                                                                                                                                                            +            'header', 
                                                                                                                                                            +            function($header, bool $replace = true, int $response_code = 0) use (&$log): void {
                                                                                                                                                            +                $log[] = $header;
                                                                                                                                                            +            }
                                                                                                                                                            +        );
                                                                                                                                                            +
                                                                                                                                                            +        header('X-Plugin-Version: 1.0.0');
                                                                                                                                                            +        header('X-Plugin-REST-Enabled: 1');
                                                                                                                                                            +        header('X-Plugin-GraphQL-Enabled: 0');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals([
                                                                                                                                                            +            [
                                                                                                                                                            +                'X-Plugin-Version' => '1.0.0',
                                                                                                                                                            +                'X-Plugin-REST-Enabled' => '1',
                                                                                                                                                            +                'X-Plugin-GraphQL-Enabled' => '0'
                                                                                                                                                            +        ], $log);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            unsetFunctionHook

                                                                                                                                                            +

                                                                                                                                                            unsetFunctionHook(string $function): void

                                                                                                                                                            +

                                                                                                                                                            Unset the hook for the function $function previously set with setFunctionHook.

                                                                                                                                                            +

                                                                                                                                                            You do not need to unset the hook for a function that was set with setFunctionHook +using unsetFunctionHook explicitly: the trait will take care of cleaning up all the modifications made to the +functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            setMethodHook

                                                                                                                                                            +

                                                                                                                                                            setMethodHook(string $class, string $method, Closure $hook): void

                                                                                                                                                            +

                                                                                                                                                            Execute $hook when entering the static or instance method $method of the class $class.

                                                                                                                                                            +

                                                                                                                                                            The keywords self and $this will be correctly bound to the class and the class instance respectively.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class LegacyApiController {
                                                                                                                                                            +    private static array $connections = [];
                                                                                                                                                            +    private ?array $cachedItems = null;
                                                                                                                                                            +
                                                                                                                                                            +    public static function connect(): self {
                                                                                                                                                            +        $connected = new self;
                                                                                                                                                            +        self::$connections[] = $connected;
                                                                                                                                                            +        return $connected;
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function getItems(int $count, int $from = 0): array {
                                                                                                                                                            +        if($this->cachedItems === null){
                                                                                                                                                            +            $this->cachedItems = wp_remote_get('https://example.com/items');
                                                                                                                                                            +        }
                                                                                                                                                            +
                                                                                                                                                            +        return array_slice($this->cachedItems, $from, $count);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_method_hook()
                                                                                                                                                            +    {
                                                                                                                                                            +        $connections = 0;
                                                                                                                                                            +        $this->setMethodHook(
                                                                                                                                                            +            LegacyApiController::class, 
                                                                                                                                                            +            'connect', 
                                                                                                                                                            +            function() use (&$connections): void {
                                                                                                                                                            +                $connections  = count(self::$connections) + 1;
                                                                                                                                                            +            }
                                                                                                                                                            +        );
                                                                                                                                                            +        $itemsCacheHits = 0;
                                                                                                                                                            +        $this->setMethodHook(
                                                                                                                                                            +            LegacyApiController::class, 
                                                                                                                                                            +            'getItems', 
                                                                                                                                                            +            function(int $count, int $from = 0) use (&$itemsCacheHit): bool {
                                                                                                                                                            +                if($this->cachedItems !== null){
                                                                                                                                                            +                    $itemsCacheHits++;
                                                                                                                                                            +                }
                                                                                                                                                            +            }
                                                                                                                                                            +        );
                                                                                                                                                            +
                                                                                                                                                            +        $connectedController1 = LegacyApiController::connect();
                                                                                                                                                            +        $connectedController2 = LegacyApiController::connect();
                                                                                                                                                            +        $connectedController1->getItems(10, 0);
                                                                                                                                                            +        $connectedController1->getItems(10, 10);
                                                                                                                                                            +        $connectedController2->getItems(10, 0);
                                                                                                                                                            +        $connectedController2->getItems(10, 10);
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals(2, $connections);
                                                                                                                                                            +        $this->assertEquals(4, $itemsCacheHits);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            unsetMethodHook

                                                                                                                                                            +

                                                                                                                                                            unsetMethodHook(string $class, string $method): void

                                                                                                                                                            +

                                                                                                                                                            Unset the hook for the static or instance method $method of the class $class previously set +with setMethodHook.

                                                                                                                                                            +

                                                                                                                                                            You do not need to unset the hook for a method that was set with seMethodHook +using unsetClassMethodHook explicitly: the trait will take care of cleaning up all the modifications made to the +functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            setConstant

                                                                                                                                                            +

                                                                                                                                                            setConstant(string $constant, mixed $value): void

                                                                                                                                                            +

                                                                                                                                                            Set the constant $constant to the value $value.

                                                                                                                                                            +

                                                                                                                                                            If the constant is not already defined, it will be defined and set to the value $value.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_constant()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setconstant('WP_ADMIN', true);
                                                                                                                                                            +        $this->setconstant('TEST_CONST', 23);
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertTrue(wp_is_admin());
                                                                                                                                                            +        $this->assertEquals(23, TEST_CONST);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            unsetConstant

                                                                                                                                                            +

                                                                                                                                                            unsetConstant(string $constant): void

                                                                                                                                                            +

                                                                                                                                                            Unset an existing constant or restores the original value of the constant if set with setConstant.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_unset_constant()
                                                                                                                                                            +    {
                                                                                                                                                            +        // The test is starting in Admin context.
                                                                                                                                                            +        $this->assertTrue(is_admin());
                                                                                                                                                            +
                                                                                                                                                            +        $this->unsetConstant('WP_ADMIN');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertFalse(is_admin());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You do not need to undefine a constant defined with setConstant using unsetConstant explicitly: the +trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each +test.

                                                                                                                                                            +

                                                                                                                                                            setClassConstant

                                                                                                                                                            +

                                                                                                                                                            setClassConstant(string $class, string $constant, mixed $value): void

                                                                                                                                                            +

                                                                                                                                                            Set the constant $constant of the class $class to the value $value.

                                                                                                                                                            +

                                                                                                                                                            If the class constant is not already defined, it will be defined and set to the value $value.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyPlugin {
                                                                                                                                                            +    const VERSION = '89.0.0';
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_class_constant()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setClassConstant(MyPlugin::class, 'VERSION', '23.89.0');
                                                                                                                                                            +        $this->setClassConstant(MyPlugin::class, 'NOT_EXISTING', 'TEST');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('23.89.0', MyPlugin::VERSION);
                                                                                                                                                            +        $this->assertEquals('TEST', MyPlugin::NOT_EXISTING);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            unsetClassConstant

                                                                                                                                                            +

                                                                                                                                                            unsetClassConstant(string $class, string $constant): void

                                                                                                                                                            +

                                                                                                                                                            Restore the constant $constant of the class $class to its original value or removes it if it was not defined.

                                                                                                                                                            +

                                                                                                                                                            You do not need to undefine a constant defined with setClassConstant +using undefineClassConstant explicitly: the trait will take care of cleaning up all the modifications made to the +functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            setClassMock

                                                                                                                                                            +

                                                                                                                                                            setClassMock(string $class, string|object $mock): void

                                                                                                                                                            +

                                                                                                                                                            Use $mock instead of $class when creating new instances of the class $class.

                                                                                                                                                            +

                                                                                                                                                            This method allows you to override magic methods as well as you would do with a normal class extension.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MockPaymentApi extends PaymentApi {
                                                                                                                                                            +    public static function version($name, $arguments){
                                                                                                                                                            +        return '23.89.0';
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_class_mock()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setClassMock(PaymentApi::class, MockPaymentApi::class);
                                                                                                                                                            +
                                                                                                                                                            +        $paymentApi = new PaymentApi();
                                                                                                                                                            +        $this->assertInstanceOf(MyPluginMock::class, $paymentApi);
                                                                                                                                                            +        $this->assertSame('23.89.0', $paymentApi::version());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If you set the $mock to an object, then the same mock object will be used for all the new instances of the +class $class:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MockPaymentApi extends PaymentApi {
                                                                                                                                                            +    public function getIds($name, $arguments){
                                                                                                                                                            +        return [1, 23, 89];
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_class_mock()
                                                                                                                                                            +    {
                                                                                                                                                            +        $mockPaymentApi = new MockPaymentApi();
                                                                                                                                                            +
                                                                                                                                                            +        $this->setClassMock(PaymentApi::class, $mockPaymentApi);
                                                                                                                                                            +
                                                                                                                                                            +        $api1 = new PaymentApi();
                                                                                                                                                            +        $this->assertSame($mockPaymentApi, $api1);
                                                                                                                                                            +        $this->assertSame([1, 23, 89], $api1->getIds());
                                                                                                                                                            +        $api2 = new PaymentApi();
                                                                                                                                                            +        $this->assertSame($mockPaymentApi, $api2);
                                                                                                                                                            +        $this->assertSame([1, 23, 89], $api2->getIds());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The $mock class, or instance, is not required to be a subclass of the class $class by the trait; although it +might be required from the code you're testing by means of type hinting.

                                                                                                                                                            +

                                                                                                                                                            If the class or method you would like to set a mock for is final, then you can combine this method with +the unsetClassFinalAttribute +and unsetMethodFinalAttribute methods to avoid the final attribute being set on the +class:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +final class LegacyPaymentApi {
                                                                                                                                                            +    public function getIds(){
                                                                                                                                                            +        // ... fetch ids from a real external API ...
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class LegacyCacheController {
                                                                                                                                                            +    protected final function get(string $key){
                                                                                                                                                            +        // ... fetch data from a real cache ...
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_class_mock()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->unsetClassFinalAttribute(LegacyPaymentApi::class);
                                                                                                                                                            +        $mockPaymentApi = new class extends LegacyPaymentApi {
                                                                                                                                                            +            public function getIds(){
                                                                                                                                                            +                return [1, 23, 89];
                                                                                                                                                            +            }
                                                                                                                                                            +        };
                                                                                                                                                            +        $this->setClassMock(LegacyPaymentApi::class, $mockPaymentApi);
                                                                                                                                                            +        $this->unsetMethodFinalAttribute(LegacyCacheController::class, 'get');
                                                                                                                                                            +        $mockCacheController = new class extends LegacyCacheController {
                                                                                                                                                            +            public function get(string $key){
                                                                                                                                                            +                return 'some-value';
                                                                                                                                                            +            }
                                                                                                                                                            +        };
                                                                                                                                                            +
                                                                                                                                                            +        $paymentApi = new LegacyPaymentApi();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertSame($mockPaymentApi, $paymentApi);
                                                                                                                                                            +        $this->assertSame([1, 23, 89], $paymentApi->getIds());
                                                                                                                                                            +
                                                                                                                                                            +        $cacheController = new LegacyCacheController();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertSame($mockCacheController, $cacheController);
                                                                                                                                                            +        $this->assertSame('some-value', $cacheController->get('some-key'));
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            unsetClassMock

                                                                                                                                                            +

                                                                                                                                                            unsetClassMock(string $class): void

                                                                                                                                                            +

                                                                                                                                                            Remove the mock for the class $class previously set with setMock.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_unset_class_mock()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setClassMock(MyPlugin::class, new MyPluginMock());
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertInstanceOf(MyPluginMock::class, new MyPlugin());
                                                                                                                                                            +
                                                                                                                                                            +        $this->unsetClassMock(MyPlugin::class);
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertInstanceOf(MyPlugin::class, new MyPlugin());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You do not need to unset the mock for a class that was set with setClassMock using unsetClassMock +explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class +attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            unsetClassFinalAttribute

                                                                                                                                                            +

                                                                                                                                                            unsetClassFinalAttribute(string $class): void

                                                                                                                                                            +

                                                                                                                                                            Remove the final attribute from the class $class.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +final class LegacyPaymentApi {}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_remove_class_final_attribute()
                                                                                                                                                            +    {
                                                                                                                                                            +        $post = static::factory()->post->createAndGet();
                                                                                                                                                            +
                                                                                                                                                            +        $this->unsetClassFinalAttribute(LegacyPaymentApi::class);
                                                                                                                                                            +
                                                                                                                                                            +        // The class is not final anymore; it can be extended for testing purposes.
                                                                                                                                                            +        $mockPaymentApi = new class extends LegacyPaymentApi {
                                                                                                                                                            +            public function getIds(){
                                                                                                                                                            +                return [1, 23, 89];
                                                                                                                                                            +            }
                                                                                                                                                            +        };
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertSame([1, 23, 89], $mockPaymentApi->getIds());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            resetClassFinalAttribute

                                                                                                                                                            +

                                                                                                                                                            resetClassFinalAttribute(string $class): void

                                                                                                                                                            +

                                                                                                                                                            Reset the final attribute of the class $class previously removed with +the unsetClassFinalAttribute method.

                                                                                                                                                            +

                                                                                                                                                            You do not need to restore the class final attribute for a class that was set +with unsetClassFinalAttribute using setClassFinalAttribute explicitly: the trait will +take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            unsetMethodFinalAttribute

                                                                                                                                                            +

                                                                                                                                                            unsetMethodFinalAttribute(string $class, string $method): void

                                                                                                                                                            +

                                                                                                                                                            Remove the final attribute from the static or instance method $method of the class $class.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_remove_method_final_attribute()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->unsetMethodFinalAttribute(LegacyAjaxController::class, 'printResponseAndExit');
                                                                                                                                                            +
                                                                                                                                                            +        // Build a class to avoid the `printResponseAndExit` method from exiting.
                                                                                                                                                            +        $testLegacyAdminController = new class extends LegacyAjaxController {
                                                                                                                                                            +            public string $response = '';
                                                                                                                                                            +
                                                                                                                                                            +            public function printResponseAndExit(){
                                                                                                                                                            +                $this->response = $this->template->render('list', return: true);
                                                                                                                                                            +                return;
                                                                                                                                                            +            }
                                                                                                                                                            +        };
                                                                                                                                                            +
                                                                                                                                                            +        // Set up things for the test ...
                                                                                                                                                            +
                                                                                                                                                            +        $testLegacyAjaxController->printResponseAndExit();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('<ul><li>Item One</li><li>Item Two</li></ul>', $testLegacyAjaxController->response);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            restoreMethodFinalAttribute

                                                                                                                                                            +

                                                                                                                                                            restoreMethodFinalAttribute(string $class, string $method): void

                                                                                                                                                            +

                                                                                                                                                            Restore the final attribute of the method static or instance $method of the class $class previously removed with +the unsetMethodFinalAttribute method.

                                                                                                                                                            +

                                                                                                                                                            You do not need to restore the method final attribute for a method that was set +with unsetMethodFinalAttribute using restoreMethodFinalAttribute explicitly: the trait +will take care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            addClassMethod

                                                                                                                                                            +

                                                                                                                                                            addClassMethod(string $class, string $method, Closure $closure, bool $static = false): void

                                                                                                                                                            +

                                                                                                                                                            Add a public static ($static = true) or instance ($static = false) method to the class $class with the +name $method and the code provided by the closure $closure.

                                                                                                                                                            +

                                                                                                                                                            Differently from the setClassMock method, this method will work on already existing instances of +the class $class, not just new instances.

                                                                                                                                                            +

                                                                                                                                                            The closure $this will be bound to the class instance.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class LegacySingletonController {
                                                                                                                                                            +    private static $instance;
                                                                                                                                                            +    private array $cache = null;
                                                                                                                                                            +    private int $cacheCount = 0;
                                                                                                                                                            +
                                                                                                                                                            +    public static function getInstance(){
                                                                                                                                                            +        if(!self::$instance){
                                                                                                                                                            +            self::$instance = new self();
                                                                                                                                                            +        }
                                                                                                                                                            +        return self::$instance;
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function getItems(int $count, int $from = 0){
                                                                                                                                                            +        if($this->cache === null){
                                                                                                                                                            +            $this->cache = wp_remote_get('https://example.com/items');
                                                                                                                                                            +            $this->cacheCount = count($cache);
                                                                                                                                                            +        }
                                                                                                                                                            +
                                                                                                                                                            +        return array_slice($this->cache, $from, $count);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_add_class_method()
                                                                                                                                                            +    {
                                                                                                                                                            +        $controller = LegacySingletonController::getInstance();
                                                                                                                                                            +
                                                                                                                                                            +        $this->addClassMethod(
                                                                                                                                                            +            LegacySingletonController::class, 
                                                                                                                                                            +            'setCache',
                                                                                                                                                            +            function(array $cache): void {
                                                                                                                                                            +                $this->cache = $cache;
                                                                                                                                                            +                $this->cacheCount = count($cache);
                                                                                                                                                            +            }
                                                                                                                                                            +        );
                                                                                                                                                            +
                                                                                                                                                            +        // Set the singletong instance cache for testing purposes.
                                                                                                                                                            +        $controller->setCache(range(1,100));
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals([1,2,3], $controller->getItems(3, 0));
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            removeClassMethod

                                                                                                                                                            +

                                                                                                                                                            removeClassMethod(string $class, string $method): void

                                                                                                                                                            +

                                                                                                                                                            Remove the static or instance method $method added with addClassMethod from the class $class.

                                                                                                                                                            +

                                                                                                                                                            You do not need to remove a method added with addClassMethod, +or addClassStaticMethod, using removeClassMethod explicitly: the trait will take care of +cleaning up all the modifications made to the functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            setObjectProperty

                                                                                                                                                            +

                                                                                                                                                            setObjectProperty(string|object $classOrObject, string $property, mixed $value): void

                                                                                                                                                            +

                                                                                                                                                            If $classOrInstance is a string, set the property $property of the class $classOrObject to the value $value. +If $classOrInstance is an object, set the property $property of the object $classOrObject to the value $value.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class Payment {
                                                                                                                                                            +    private string $uuid;
                                                                                                                                                            +    private string $from;
                                                                                                                                                            +    private string $to;
                                                                                                                                                            +
                                                                                                                                                            +    public function __construct(string $from, $string $to){
                                                                                                                                                            +        $this->uuid = UUID::generate();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function getHash(): string {
                                                                                                                                                            +        return wp_hash(serialize([
                                                                                                                                                            +            'uuid' => $this->uuid
                                                                                                                                                            +            'from' => $this->from,
                                                                                                                                                            +            'to' => $this->to
                                                                                                                                                            +        ]));
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_object_property()
                                                                                                                                                            +    {
                                                                                                                                                            +        $payment = new Payment('Bob', 'Alice');
                                                                                                                                                            +
                                                                                                                                                            +        $this->setObjectProperty($payment, 'uuid', '550e8400-e29b-41d4-a716-446655440000');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals(wp_hash(serialize([
                                                                                                                                                            +            'uuid' => '550e8400-e29b-41d4-a716-446655440000',
                                                                                                                                                            +            'from' => 'Bob',
                                                                                                                                                            +            'to' => 'Alice'
                                                                                                                                                            +        ])), $payment->getHash());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You do not need to reset the property of an object that was set with setObjectProperty explicitly: the trait will take +care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            getObjectProperty

                                                                                                                                                            +

                                                                                                                                                            getObjectProperty(object $object, string $property): mixed

                                                                                                                                                            +

                                                                                                                                                            Get the value of the static or instance property $property of the object $object.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class LegacyController {
                                                                                                                                                            +    private Template $template;
                                                                                                                                                            +
                                                                                                                                                            +    public function __construct(){
                                                                                                                                                            +        $this->template = new Template();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // ...
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_get_object_property()
                                                                                                                                                            +    {
                                                                                                                                                            +        $controller = new LegacyController();
                                                                                                                                                            +
                                                                                                                                                            +        $templateEngine $this->getObjectProperty($controller, 'template'));
                                                                                                                                                            +
                                                                                                                                                            +        // ... do something with the template ...
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            resetObjectProperty

                                                                                                                                                            +

                                                                                                                                                            resetObjectProperty(string|object $classOrObject, string $property): void

                                                                                                                                                            +

                                                                                                                                                            Reset the property $property of the class $class or object $object to its original value.

                                                                                                                                                            +

                                                                                                                                                            You do not need to reset the property of an object that was set with setObjectProperty explicitly: the trait will take +care of cleaning up all the modifications made to the functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            getMethodStaticVariables

                                                                                                                                                            +

                                                                                                                                                            getMethodStaticVariables(string $class, string $method): array

                                                                                                                                                            +

                                                                                                                                                            Get the value of the static variables of the class $class and method $method.

                                                                                                                                                            +

                                                                                                                                                            The method will work for both static and instance methods of the class $class.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class RequestLogger {
                                                                                                                                                            +    public function log(int $code, string $response):void {
                                                                                                                                                            +        static $requestId;
                                                                                                                                                            +
                                                                                                                                                            +        if($requestId === null){
                                                                                                                                                            +            $requestId = md5(microtime());
                                                                                                                                                            +        }
                                                                                                                                                            +
                                                                                                                                                            +        printf("Request %s: %d %s\n", $requestId, $code, $response);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_get_class_method_static_variables()
                                                                                                                                                            +    {
                                                                                                                                                            +        $requestLogger = new RequestLogger();
                                                                                                                                                            +
                                                                                                                                                            +        ob_start();
                                                                                                                                                            +        $requestLogger->log(200, 'OK');
                                                                                                                                                            +        $requestLogger->log(403, 'Forbidden');
                                                                                                                                                            +        $requestLogger->log(200, 'OK');
                                                                                                                                                            +        $buffer = ob_get_clean();
                                                                                                                                                            +
                                                                                                                                                            +        $requestId = $this->getClassMethodStaticVariables(RequestLogger::class, 'log')['requestId'];
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals("Request $requestId: 200 OK\nRequest $requestId: 403 Forbidden\nRequest $requestId: 200 OK\n", $buffer);
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            setMethodStaticVariables

                                                                                                                                                            +

                                                                                                                                                            setMethodStaticVariables(string $class, string $method, array $values): void

                                                                                                                                                            +

                                                                                                                                                            Set the static variablesof the class $class and method $method to the values $values.

                                                                                                                                                            +

                                                                                                                                                            This will work on both static and instance methods.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class ListComponent {
                                                                                                                                                            +    public function render(){
                                                                                                                                                            +        static $hash;
                                                                                                                                                            +
                                                                                                                                                            +        if(!$hash){
                                                                                                                                                            +            $hash = md5(microtime());
                                                                                                                                                            +        }
                                                                                                                                                            +
                                                                                                                                                            +        return '<ul screen=' . $hash . '><li>Item One</li><li>Item Two</li></ul>';
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_class_method_static_variables()
                                                                                                                                                            +    {
                                                                                                                                                            +        $newValues = array_merge(
                                                                                                                                                            +            $this->getMethodStaticVariables(ListComponent::class, 'render'),
                                                                                                                                                            +            ['hash' => 'some-hash']
                                                                                                                                                            +        );
                                                                                                                                                            +        $this->setClassMethodStaticVariables( ListComponent::class, 'render', [
                                                                                                                                                            +          'hash' => 'some-hash'
                                                                                                                                                            +        ]);
                                                                                                                                                            +
                                                                                                                                                            +        $component = new ListComponent();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals(
                                                                                                                                                            +            '<ul data-screen="some-hash"><li>Item One</li><li>Item Two</li></ul>', 
                                                                                                                                                            +            $component->render()
                                                                                                                                                            +        );
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You do not need to reset the static variable of a class method that was set with setMethodStaticVariables explicitly +using resetMethodStaticVariables explicitly: the trait will take care of cleaning up all the modifications made to the +functions, methods and class attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            resetMethodStaticVariables

                                                                                                                                                            +

                                                                                                                                                            resetMethodStaticVariables(string $class, string $method): void

                                                                                                                                                            +

                                                                                                                                                            Resets the static variables of the class $class method $method to their original values.

                                                                                                                                                            +

                                                                                                                                                            setFunctionStaticVariable

                                                                                                                                                            +

                                                                                                                                                            setFunctionStaticVariables(string $function, string $variable, mixed $value): void

                                                                                                                                                            +

                                                                                                                                                            Set the static variable $variable of the function $function to the value $value.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +function renderScreen(): string{
                                                                                                                                                            +    static $rendered;
                                                                                                                                                            +
                                                                                                                                                            +    if($rendered){
                                                                                                                                                            +        return;
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    $html = '<p>Some HTML</p>';
                                                                                                                                                            +
                                                                                                                                                            +    $rendered = true;
                                                                                                                                                            +
                                                                                                                                                            +    return $html;
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_function_static_variables()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->setFunctionStaticVariables('renderScreen', ['rendered' => false]);
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('<p>Some HTML</p>', renderScreen());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You do not need to reset the value of a function static variable set using the resetFunctionStaticVariables method +explicitly: the trait will take care of cleaning up all the modifications made to the functions, methods and class +attributes after each test.

                                                                                                                                                            +

                                                                                                                                                            getFunctionStaticVariables

                                                                                                                                                            +

                                                                                                                                                            getFunctionStaticVariables(string $function, ): array

                                                                                                                                                            +

                                                                                                                                                            Get the value of the static variable $variable of the function $function.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +function renderScreen(): string {
                                                                                                                                                            +    static $screenHash;
                                                                                                                                                            +
                                                                                                                                                            +    if(!$screenHash){
                                                                                                                                                            +        $screenHash = md5(microtime());
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    return '<p data-screen="' . $screenHash . '">Some HTML</p>';
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_set_function_static_variables()
                                                                                                                                                            +    {
                                                                                                                                                            +        $screenHash = $this->getFunctionStaticVariables('renderScreen')['screenHash'];
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('<p data-screen="' . $screenHash . '">Some HTML</p>', renderScreen());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            resetFunctionStaticVariables

                                                                                                                                                            +

                                                                                                                                                            resetFunctionStaticVariables(string $function): void

                                                                                                                                                            +

                                                                                                                                                            Resets the static variables of the function $function set with the setFunctionStaticVariables method.

                                                                                                                                                            +

                                                                                                                                                            addFunction

                                                                                                                                                            +

                                                                                                                                                            addFunction(string $function, Closure $closure): void

                                                                                                                                                            +

                                                                                                                                                            Add a global or namespaced function to the current scope.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_add_function()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->addFunction('myGlobalFunction', fn() => 23);
                                                                                                                                                            +        $this->addFunction('Acme\Project\namespacedFunction', fn() => 89);
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals(23, myGlobalFunction());
                                                                                                                                                            +        $this->assertEquals(89, Acme\Project\namespacedFunction());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            removeFunction

                                                                                                                                                            +

                                                                                                                                                            removeFunction(string $function): void

                                                                                                                                                            +

                                                                                                                                                            Removes the global or namespaced function $function from the current scope. +This will work for functions defined using the addFunction method or defined elsewhere.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_add_function()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->addFunction('myGlobalFunction', fn() => 23);
                                                                                                                                                            +        $this->addFunction('Acme\Project\namespacedFunction', fn() => 89);
                                                                                                                                                            +
                                                                                                                                                            +        $this->removeFunction('some_plugin_function');
                                                                                                                                                            +        $this->removeFunction('Acme\Project\namespacedFunction');
                                                                                                                                                            +
                                                                                                                                                            +        // Added with addFunction.
                                                                                                                                                            +        $this->assertFalse(function_exists('myGlobalFunction');
                                                                                                                                                            +        $this->assertFalse(function_exists('Acme\Project\namespacedFunction');
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertFalse(function_exists('some_plugin_function');
                                                                                                                                                            +        $this->assertFalse(function_exists('Another\Plugin\some_function');
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You do not need to remove a function added with addFunction using removeFunction explicitly: the +trait will take care of cleaning up all the modifications made to the functions, methods and class attributes after each +test.

                                                                                                                                                            +

                                                                                                                                                            preventExit

                                                                                                                                                            +

                                                                                                                                                            preventExit(): void

                                                                                                                                                            +

                                                                                                                                                            Prevents exit or die calls executed after the method from terminating the PHP process calling exit or die.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use lucatume\WPBrowser\Traits\UopzFunctions;
                                                                                                                                                            +use lucatume\WPBrowser\TestCase\WPTestCase;
                                                                                                                                                            +
                                                                                                                                                            +function printAndDie(): void{
                                                                                                                                                            +    print 'Some HTML';
                                                                                                                                                            +    die();
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class MyTest extends WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    use UopzFunctions;
                                                                                                                                                            +
                                                                                                                                                            +    public function test_can_prevent_exit()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->preventExit();
                                                                                                                                                            +
                                                                                                                                                            +        ob_start();
                                                                                                                                                            +        printAndDie();
                                                                                                                                                            +        $buffer = ob_get_clean();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertEquals('Some HTML', $buffer);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            restoreExit

                                                                                                                                                            +

                                                                                                                                                            allowExit(): void

                                                                                                                                                            +

                                                                                                                                                            Restores the original behavior of the exit and die functions.

                                                                                                                                                            +

                                                                                                                                                            You do not need to restore the exit behavior for a exit that was prevented using preventExit +using allowExit explicitly: the trait will take care of cleaning up all the modifications made to the functions, +methods and class attributes after each test.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/troubleshooting/index.html b/troubleshooting/index.html new file mode 100644 index 000000000..21708d7c0 --- /dev/null +++ b/troubleshooting/index.html @@ -0,0 +1,2974 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Troubleshooting - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Troubleshooting

                                                                                                                                                            + +

                                                                                                                                                            Troubleshooting common issues

                                                                                                                                                            +

                                                                                                                                                            Downloads fail in Windows

                                                                                                                                                            +

                                                                                                                                                            If you're using code or commands, e.g. the chromedriver:update one, that download files and those keep failing with a message like the following:

                                                                                                                                                            +
                                                                                                                                                            File ... download failed: SSL certificate problem: unable to get local issuer certificate
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            It's likely the issue originates from PHP not having access to the system certificate store.

                                                                                                                                                            +

                                                                                                                                                            You can fix this by downloading the certificates file and setting the curl.cainfo and openssl.cafile PHP configuration options to point to it:

                                                                                                                                                            +
                                                                                                                                                            curl.cainfo = "C:\path\to\cacert.pem"
                                                                                                                                                            +openssl.cafile = "C:\path\to\cacert.pem"
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/advanced/run-in-separate-process/index.html b/v3/advanced/run-in-separate-process/index.html new file mode 100644 index 000000000..fa816c71f --- /dev/null +++ b/v3/advanced/run-in-separate-process/index.html @@ -0,0 +1,3239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Running tests in separate processes - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Running tests in separate processes

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Running tests in separate processes

                                                                                                                                                            +

                                                                                                                                                            PHPUnit offers the possibility to run tests in a separate PHP process; Codeception does not officially support the option as of version 4.0.

                                                                                                                                                            +

                                                                                                                                                            The wp-browser project tries to fill that gap by supporting the @runInSeparateProcess annotation.
                                                                                                                                                            +This support comes with some caveats, though:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            1. The support is only for test cases extending the Codeception\TestCase\WPTestCase class (the base test case for integration or "WordPress unit" tests)
                                                                                                                                                            2. +
                                                                                                                                                            3. The support wp-browser provides only supports the @preserveGlobalState annotation with the disabled value; this means there is no support for preserving global state between tests.
                                                                                                                                                            4. +
                                                                                                                                                            +

                                                                                                                                                            Read more about what this means in PHPUnit documentation.

                                                                                                                                                            +

                                                                                                                                                            Why run tests in a separate PHP process?

                                                                                                                                                            +

                                                                                                                                                            One main reason: isolation.

                                                                                                                                                            +

                                                                                                                                                            What does "isolation" means?

                                                                                                                                                            +

                                                                                                                                                            Before answering that question, it's essential to understand, via an example, why a lack of isolation might be an issue.

                                                                                                                                                            +

                                                                                                                                                            I want to test the get_api function. The function will return the correct singleton instance of an API handling class: an instance of Api when the function is called in non-admin context, and an instance of AdminApi when the function is called in admin context. The get_api function is acting as a service locator.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +function get_api(){
                                                                                                                                                            +    static $api;
                                                                                                                                                            +
                                                                                                                                                            +    if(null !== $api){
                                                                                                                                                            +        return $api;
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    if( is_admin() ) {
                                                                                                                                                            +        $api = new Admin_Api();
                                                                                                                                                            +    } else {
                                                                                                                                                            +        $api = new Api();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    return $api;
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            There are two challenges to testing this function:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            1. The is_admin function, defined by WordPress, looks up a WP_ADMIN constant to know if the context of the current request is an administration UI one or not.
                                                                                                                                                            2. +
                                                                                                                                                            3. The get_api function will check for the context and resolve and build the correct instance only once, the first time it's called in the context of a request.
                                                                                                                                                            4. +
                                                                                                                                                            +

                                                                                                                                                            There are some possible solutions to this problem:

                                                                                                                                                            +

                                                                                                                                                            a. Refactor the get_api function into a method of an Api_Factory object taking the context as a dependency, thus allowing injection of the "context" (which implies the creation of a Context adapter that will proxy its is_admin method to the is_admin function). You can find the code for such refactoring in the OOP refactoring of get_api section. +b. Refactor the get_api function to accept the current is_admin value as an input argument, get_api( $is_admin ), this refactoring moves part of the complexity of getting hold of the correct instance of the API handler on the client code. Adding more build condition and checks, e.g., if the current request is a REST request or not or some tests on the user authorizations, then, requires adding more input arguments to the get_api function: the knowledge of the implementation of the get_api method will "leak" to the client code having to replicate complexity throughout the system.

                                                                                                                                                            +

                                                                                                                                                            I want to layout possible solutions to the problem to show there is always a design alternative to make code testable that might or might not fit the current time or scope constraint.

                                                                                                                                                            +

                                                                                                                                                            In this example, I've inherited the get_api function from the existing code, and it cannot be changed, yet I want to test it dealing with the two problems outlined above.

                                                                                                                                                            +

                                                                                                                                                            Running tests in separate PHP processes

                                                                                                                                                            +

                                                                                                                                                            To test the get_api function shown above I've created a new wpunit type of test:

                                                                                                                                                            +
                                                                                                                                                            vendor/bin/codecept g:wpunit integration "api"
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command scaffolds a test/integration/apiTest.php file that I've modified to ensure full coverage of the get_api function:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class apiTest extends \Codeception\TestCase\WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function test_get_api_exists()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->assertTrue(function_exists('get_api'));
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_get_api_will_cache()
                                                                                                                                                            +    {
                                                                                                                                                            +        $this->assertSame(get_api(), get_api());
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    /**
                                                                                                                                                            +     * @runInSeparateProcess
                                                                                                                                                            +     * @preserveGlobalState disabled
                                                                                                                                                            +     */
                                                                                                                                                            +    public function test_get_api_will_return_api_if_not_admin()
                                                                                                                                                            +    {
                                                                                                                                                            +        // Let's make sure we're NOT in admin context.
                                                                                                                                                            +        define('WP_ADMIN', false);
                                                                                                                                                            +
                                                                                                                                                            +        $api = get_api();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertInstanceOf(Api::class, $api);
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    /**
                                                                                                                                                            +     * @runInSeparateProcess
                                                                                                                                                            +     * @preserveGlobalState disabled
                                                                                                                                                            +     */
                                                                                                                                                            +    public function test_get_api_will_cache_api_if_not_admin()
                                                                                                                                                            +    {
                                                                                                                                                            +        // Let's make sure we're NOT in admin context.
                                                                                                                                                            +        define('WP_ADMIN', false);
                                                                                                                                                            +
                                                                                                                                                            +        $api = get_api();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertSame(get_api(), $api);
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    /**
                                                                                                                                                            +     * @runInSeparateProcess
                                                                                                                                                            +     * @preserveGlobalState disabled
                                                                                                                                                            +     */
                                                                                                                                                            +    public function test_get_api_will_return_api_if_is_admin()
                                                                                                                                                            +    {
                                                                                                                                                            +        // Let's make sure we're NOT in admin context.
                                                                                                                                                            +        define('WP_ADMIN', true);
                                                                                                                                                            +
                                                                                                                                                            +        $api = get_api();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertInstanceOf(AdminApi::class, $api);
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    /**
                                                                                                                                                            +     * @runInSeparateProcess
                                                                                                                                                            +     * @preserveGlobalState disabled
                                                                                                                                                            +     */
                                                                                                                                                            +    public function test_get_api_will_cache_api_if_is_admin()
                                                                                                                                                            +    {
                                                                                                                                                            +        // Let's make sure we're NOT in admin context.
                                                                                                                                                            +        define('WP_ADMIN', true);
                                                                                                                                                            +
                                                                                                                                                            +        $api = get_api();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertSame(get_api(), $api);
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Some pieces of this code are worth pointing out:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            1. There are two test methods, test_get_api_exists and test_get_api_will_cache that are not running in a separate process. Running tests in a separate process provide isolation at the cost of speed, only tests that require isolation should run in a separate PHP process.
                                                                                                                                                            2. +
                                                                                                                                                            3. I instruct the Codeception and PHPUnit test runner to run a test method in a different process by adding two annotations that are both required ** precisely as shown**: +
                                                                                                                                                              /**
                                                                                                                                                              + * @runInSeparateProcess
                                                                                                                                                              + * @preserveGlobalState disabled
                                                                                                                                                              + */
                                                                                                                                                              +
                                                                                                                                                            4. +
                                                                                                                                                            5. The isolation part of this testing approach shines through when I define, in the last four tests, the WP_ADMIN constant multiple times. If I try to do that in test code running in the same PHP process, then the second define call would cause a fatal error.
                                                                                                                                                            6. +
                                                                                                                                                            7. The isolation has also taken care of the second issue where the get_api function caches the $api instance after its first resolution in a static variable: since each test happens in a self-contained, dedicated PHP process, the static $api variable will be null at the start of each test.
                                                                                                                                                            8. +
                                                                                                                                                            +

                                                                                                                                                            Can I run some tests in the same process and some in a separate process?

                                                                                                                                                            +

                                                                                                                                                            Yes. In the example test code in the previous section, the test_get_api_exists and test_get_api_will_cache test methods are not running in separate processes.

                                                                                                                                                            +

                                                                                                                                                            In your test cases extending the Codeception\TestCase\WPTestCase, you can mix test methods running in the primary PHP process and those running in a separate PHP process without issues.

                                                                                                                                                            +

                                                                                                                                                            OOP refactoring of get_api

                                                                                                                                                            +

                                                                                                                                                            In the Why run tests in a separate PHP process? section I've outlined a possible refactoring of the get_api function to make it testable without requiring the use of separate PHP processes.

                                                                                                                                                            +

                                                                                                                                                            I'm providing this refactoring code below for the sake of completeness, the judgment of which approach is "better" is up to the reader.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class Context_Adapter{
                                                                                                                                                            +
                                                                                                                                                            +    public function is_admin(){
                                                                                                                                                            +        return \is_admin();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +class Api_Factory{
                                                                                                                                                            +
                                                                                                                                                            +    private $api;
                                                                                                                                                            +    private $context;
                                                                                                                                                            +
                                                                                                                                                            +    public function __construct(Context_Adapter $context){
                                                                                                                                                            +        $this->context = $context;
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function getApi(){
                                                                                                                                                            +        if(null !== $this->api){
                                                                                                                                                            +            return $this->api;    
                                                                                                                                                            +        }
                                                                                                                                                            +
                                                                                                                                                            +        if($this->context->is_admin()){
                                                                                                                                                            +            $api = new Admin_Api;
                                                                                                                                                            +        } else {
                                                                                                                                                            +            $api = new Api;
                                                                                                                                                            +        }
                                                                                                                                                            +
                                                                                                                                                            +        return $api;
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Now the Api_Factory class can be injected by injecting a mocked Context_Adapter class, modifying the return value of the Context_Adapter::is_admin method.

                                                                                                                                                            +

                                                                                                                                                            Due to the supposed requirement of the API instance being a singleton, this solution will also require some container or service-locator to ensure at most only one instance of the Api_Factory exists at any given time in the context of a request.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/codeception-4-support/index.html b/v3/codeception-4-support/index.html new file mode 100644 index 000000000..4ae884dd2 --- /dev/null +++ b/v3/codeception-4-support/index.html @@ -0,0 +1,2983 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Using wp-browser with Codeception 4.0 - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Using wp-browser with Codeception 4.0

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Using wp-browser with Codeception 4.0

                                                                                                                                                            +

                                                                                                                                                            Codeception version 4.0 introduced a number of new features to the framework and it's the version of wp-browser that will be maintained from now on.

                                                                                                                                                            +

                                                                                                                                                            I've made an effort to keep wp-browser compatible with PHP 5.6 and Codeception versions from 2.5 up.

                                                                                                                                                            +

                                                                                                                                                            One the biggest changes of Codeception version 4.0 is that modules have been broken out into separate packages.
                                                                                                                                                            +To use wp-browser with Codeception 4.0 all you need to do is to add this to your project composer.json file:

                                                                                                                                                            +
                                                                                                                                                            {
                                                                                                                                                            +  "require-dev": {
                                                                                                                                                            +    "lucatume/wp-browser": "^2.4",
                                                                                                                                                            +    "codeception/module-asserts": "^1.0",
                                                                                                                                                            +    "codeception/module-phpbrowser": "^1.0",
                                                                                                                                                            +    "codeception/module-webdriver": "^1.0",
                                                                                                                                                            +    "codeception/module-db": "^1.0",
                                                                                                                                                            +    "codeception/module-filesystem": "^1.0",
                                                                                                                                                            +    "codeception/module-cli": "^1.0",
                                                                                                                                                            +    "codeception/util-universalframework": "^1.0"
                                                                                                                                                            +  }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You might not need all the modules listed here, depending on the wp-browser modules you use in your test suites.
                                                                                                                                                            +This is a scheme of what Codeception modules you will need for which wp-browser module to help you choose only the required modules:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • "codeception/module-asserts" - Required for Codeception 4.0 compatibility.
                                                                                                                                                            • +
                                                                                                                                                            • "codeception/module-phpbrowser" - Required by the WPBrowser module.
                                                                                                                                                            • +
                                                                                                                                                            • "codeception/module-webdriver" - Required by the WPWebDriver module.
                                                                                                                                                            • +
                                                                                                                                                            • "codeception/module-db" - Required by the WPDb module.
                                                                                                                                                            • +
                                                                                                                                                            • "codeception/module-filesystem" - Required by the WPFilesystem module.
                                                                                                                                                            • +
                                                                                                                                                            • "codeception/module-cli" - Required by the WPCLI module.
                                                                                                                                                            • +
                                                                                                                                                            • "codeception/util-universalframework" - Required by the WordPress framework module.
                                                                                                                                                            • +
                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/codeception-phpunit-and-wpbrowser/index.html b/v3/codeception-phpunit-and-wpbrowser/index.html new file mode 100644 index 000000000..eb0c3a654 --- /dev/null +++ b/v3/codeception-phpunit-and-wpbrowser/index.html @@ -0,0 +1,3049 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Codeception, PHPUnit and wp-browser - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Codeception, PHPUnit and wp-browser

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The wp-browser stack

                                                                                                                                                            +

                                                                                                                                                            The wp-browser project is built leveraging the power of a number of open-source projects.

                                                                                                                                                            +

                                                                                                                                                            While I'm not listing all of them here it's worth mentioning those that will come up, again and again, in the documentation.

                                                                                                                                                            +

                                                                                                                                                            WordPress

                                                                                                                                                            +

                                                                                                                                                            WordPress is open source software you can use to create a beautiful website, blog, or app.

                                                                                                                                                            +

                                                                                                                                                            The line is taken directly from WordPress.org site.

                                                                                                                                                            +

                                                                                                                                                            In the context of this documentation WordPress is the PHP and JavaScript framework websites and web applications can be built on, the one anyone can download from here.

                                                                                                                                                            +

                                                                                                                                                            Codeception

                                                                                                                                                            +

                                                                                                                                                            Codeception (home) is a modern, powerful PHP testing framework written in PHP.

                                                                                                                                                            +

                                                                                                                                                            It comes with a number of modules and extensions that are comparable to WordPress plugins and themes.

                                                                                                                                                            +

                                                                                                                                                            Modules and extensions are combined in suites to be able to run a specific type of test. Each suite will handle a specific type of test for a specific set of code.

                                                                                                                                                            +

                                                                                                                                                            wp-browser is none other than a collection of modules and extensions for Codeception made specifically to test WordPress applications.

                                                                                                                                                            +

                                                                                                                                                            PHPUnit

                                                                                                                                                            +

                                                                                                                                                            PHPUnit is the most widely known PHP testing framework. As the name implies it was born to make unit testing of PHP code easier but its scope and power has grown well below that.

                                                                                                                                                            +

                                                                                                                                                            Codeception is based, and uses, PhpUnit to wrap some of its functionalities into an easy-to-use API.
                                                                                                                                                            +The two are so compatible one with the other that Codeception can run PHPUnit tests with little to no changes.

                                                                                                                                                            +

                                                                                                                                                            This documentation will not cover this subject and will only deal with Codeception-native test methods but you can find more information here.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/commands/index.html b/v3/commands/index.html new file mode 100644 index 000000000..ac9bd7592 --- /dev/null +++ b/v3/commands/index.html @@ -0,0 +1,3348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Commands - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Custom commands provided by wp-browser

                                                                                                                                                            +

                                                                                                                                                            The project comes with its own set of custom Codeception commands.

                                                                                                                                                            +

                                                                                                                                                            The commands provide functionalities to quickly scaffold different types of tests. +Any other codecept command remains intact and available.

                                                                                                                                                            +

                                                                                                                                                            Adding the commands to an existing project

                                                                                                                                                            +

                                                                                                                                                            The commands are added to the main Codeception configuration file, codeception.yml, when scaffolding a project via the codecept init wp-browser command.

                                                                                                                                                            +

                                                                                                                                                            They can be added to any existing project adding, or editing, the commands section of the configuration file:

                                                                                                                                                            +
                                                                                                                                                            extensions:
                                                                                                                                                            +    commands:
                                                                                                                                                            +        - "Codeception\\Command\\GenerateWPUnit"
                                                                                                                                                            +        - "Codeception\\Command\\GenerateWPRestApi"
                                                                                                                                                            +        - "Codeception\\Command\\GenerateWPRestController"
                                                                                                                                                            +        - "Codeception\\Command\\GenerateWPRestPostTypeController"
                                                                                                                                                            +        - "Codeception\\Command\\GenerateWPAjax"
                                                                                                                                                            +        - "Codeception\\Command\\GenerateWPCanonical"
                                                                                                                                                            +        - "Codeception\\Command\\GenerateWPXMLRPC"
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Generation commands

                                                                                                                                                            +

                                                                                                                                                            The library provides commands to quickly scaffold integration test cases for specific types of WordPress components, see levels of testing for more information.

                                                                                                                                                            +

                                                                                                                                                            The tests are almost identical to the ones you could write in a PHPUnit based Core suite with the exception of extending the Codeception\TestCase\WPTestCase test case.

                                                                                                                                                            +

                                                                                                                                                            generate:wpunit

                                                                                                                                                            +

                                                                                                                                                            Generates a test case extending the \Codeception\TestCase\WPTestCase class using the

                                                                                                                                                            +
                                                                                                                                                              codecept generate:wpunit suite SomeClass
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command will generate a skeleton test case like

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class SomeClassTest extends \Codeception\TestCase\WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function setUp()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::setUp();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function tearDown()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::tearDown();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // tests
                                                                                                                                                            +    public function testMe()
                                                                                                                                                            +    {
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            generate:wprest

                                                                                                                                                            +

                                                                                                                                                            Generates a test case extending the \Codeception\TestCase\WPRestApiTestCase class using the

                                                                                                                                                            +
                                                                                                                                                              codecept generate:wprest suite SomeClass
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command will generate a skeleton test case like

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class SomeClassTest extends \Codeception\TestCase\WPRestApiTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function setUp()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::setUp();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function tearDown()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::tearDown();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // tests
                                                                                                                                                            +    public function testMe()
                                                                                                                                                            +    {
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            generate:wprestcontroller

                                                                                                                                                            +

                                                                                                                                                            Generates a test case extending the \Codeception\TestCase\WPRestControllerTestCase class using the

                                                                                                                                                            +
                                                                                                                                                              codecept generate:wprest suite SomeClass
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command will generate a skeleton test case like

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class SomeClassTest extends \Codeception\TestCase\WPRestControllerTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function setUp()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::setUp();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function tearDown()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::tearDown();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // tests
                                                                                                                                                            +    public function testMe()
                                                                                                                                                            +    {
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            generate:wprestposttypecontroller

                                                                                                                                                            +

                                                                                                                                                            Generates a test case extending the \Codeception\TestCase\WPRestPostTypeControllerTestCase class using the

                                                                                                                                                            +
                                                                                                                                                              codecept generate:wprest suite SomeClass
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command will generate a skeleton test case like

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class SomeClassTest extends \Codeception\TestCase\WPRestPostTypeControllerTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function setUp()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::setUp();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function tearDown()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::tearDown();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // tests
                                                                                                                                                            +    public function testMe()
                                                                                                                                                            +    {
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            generate:wpajax

                                                                                                                                                            +

                                                                                                                                                            Generates a test case extending the \Codeception\TestCase\WPAjaxTestCase class using the

                                                                                                                                                            +
                                                                                                                                                              codecept generate:wpajax suite SomeClass
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command will generate a skeleton test case like

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class SomeClassTest extends \Codeception\TestCase\WPAjaxTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function setUp()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::setUp();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function tearDown()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::tearDown();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // tests
                                                                                                                                                            +    public function testMe()
                                                                                                                                                            +    {
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            generate:wpxmlrpc

                                                                                                                                                            +

                                                                                                                                                            Generates a test case extending the \Codeception\TestCase\WPXMLRPCTestCase class using the

                                                                                                                                                            +
                                                                                                                                                              codecept generate:wpxmlrpc suite SomeClass
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command will generate a skeleton test case like

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class SomeClassTest extends \Codeception\TestCase\WPXMLRPCTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function setUp()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::setUp();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function tearDown()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::tearDown();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // tests
                                                                                                                                                            +    public function testMe()
                                                                                                                                                            +    {
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            generate:wpcanonical

                                                                                                                                                            +

                                                                                                                                                            Generates a test case extending the \Codeception\TestCase\WPCanonicalTestCase class using the

                                                                                                                                                            +
                                                                                                                                                              codecept generate:wpcanonical suite SomeClass
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The command will generate a skeleton test case like

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +class SomeClassTest extends \Codeception\TestCase\WPCanonicalTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function setUp()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::setUp();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function tearDown()
                                                                                                                                                            +    {
                                                                                                                                                            +      parent::tearDown();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    // tests
                                                                                                                                                            +    public function testMe()
                                                                                                                                                            +    {
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/configuration/index.html b/v3/configuration/index.html new file mode 100644 index 000000000..41c0adccc --- /dev/null +++ b/v3/configuration/index.html @@ -0,0 +1,3930 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configuration - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Configuration

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Initializing wp-browser

                                                                                                                                                            +

                                                                                                                                                            While wp-browser can be configured manually creating each file the fastest way to bootstrap its configuration is by using its initialization template.

                                                                                                                                                            +

                                                                                                                                                            Throughout the steps below I will use the WordPress setup I've prepared before +From the root folder of the project, /Users/luca/Sites/wordpress/wp-content/plugins/acme-plugin in the example, run the command:

                                                                                                                                                            +
                                                                                                                                                            vendor/bin/codecept init wpbrowser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Composer installed Codeception binary (codecept) in the vendor folder of my project.

                                                                                                                                                            +

                                                                                                                                                            With the command above I'm telling Codeception to initialize a wp-browser project in the current folder.
                                                                                                                                                            +When I click enter I'm presented with a list of questions, each answer will be used to configure the wp-browser project for me; one by one.

                                                                                                                                                            +

                                                                                                                                                            In the screenshot the answers I've provided to each question, with reference to the setup above:

                                                                                                                                                            +

                                                                                                                                                            codecept init wpbrowser 1

                                                                                                                                                            +

                                                                                                                                                            codecept init wpbrowser 2

                                                                                                                                                            +

                                                                                                                                                            wp-browser will try to provide a brief explanation of what each question is but below is the long version.

                                                                                                                                                            +

                                                                                                                                                            Long question explanation

                                                                                                                                                            +

                                                                                                                                                            I've tried to condense as much clarity as possible in the questions the codecept init wpbrowser command will ask but, for sake of brevity and space, there's no way I could provide inline a deeper explanation of each.

                                                                                                                                                            +

                                                                                                                                                            Below is a longer explanation of each question:

                                                                                                                                                            + +

                                                                                                                                                            How would you like the acceptance suite to be called?

                                                                                                                                                            +

                                                                                                                                                            With reference to the testing levels definition this question provides you with the possibility to change the name of the acceptance-like test suite.

                                                                                                                                                            +

                                                                                                                                                            Common, alternative, names are ui, rest and user.

                                                                                                                                                            +

                                                                                                                                                            How would you like the functional suite to be called?

                                                                                                                                                            +

                                                                                                                                                            With reference to the testing levels definition this question provides you with the possibility to change the name of the functional-like test suite.

                                                                                                                                                            +

                                                                                                                                                            A common alternative name is service.

                                                                                                                                                            +

                                                                                                                                                            How would you like the WordPress unit and integration suite to be called?

                                                                                                                                                            +

                                                                                                                                                            With reference to the testing levels definition this question provides you with the possibility to change the name of the suite dedicated to integration and "WordPress unit" tests.

                                                                                                                                                            +

                                                                                                                                                            A common alternative name is integration.

                                                                                                                                                            +

                                                                                                                                                            How would you like to call the env configuration file?

                                                                                                                                                            +

                                                                                                                                                            Instead of configuring each module in each suite with the same parameters over and over Codeception supports dynamic configuration via environment files.

                                                                                                                                                            +

                                                                                                                                                            wp-browser will scaffold such a configuration for you and will use, by default, a file called .env to store the configuration parameters.

                                                                                                                                                            +

                                                                                                                                                            The file name might not suit all setups especially and this question allows changing that file name; common, alternative, file names are .env.tests, .env.codeception and similar.

                                                                                                                                                            +

                                                                                                                                                            Where is WordPress installed?

                                                                                                                                                            +

                                                                                                                                                            During tests the test code will need to access WordPress code, precisely wp-browser requires being pointed to the folder that contains the wp-load.php file.

                                                                                                                                                            +

                                                                                                                                                            The answer can be an absolute path, like /Users/luca/Sites/wordrpress, or a path relative to the folder where Codeception is installed like vendor/wordpress.

                                                                                                                                                            +

                                                                                                                                                            This path should be accessible by the machine that is running the tests; if you're running the tests from your machine (e.g. your laptop) that's just the path to the folder where WordPress is installed, /Users/luca/Sites/wordpress in the example configuration above.

                                                                                                                                                            +

                                                                                                                                                            If you are, instead, running the tests from within a virtualized machine (e.g. Vagrant or Docker) then the path should be the one used by the virtualized machine.

                                                                                                                                                            +

                                                                                                                                                            To make an example:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • on my machine WordPress is installed at /Users/luca/Sites/wordpress
                                                                                                                                                            • +
                                                                                                                                                            • I've created a Docker container using the official WordPress image and bound the above folder into the container
                                                                                                                                                            • +
                                                                                                                                                            • internally the container will put WordPress in the /var/www/html folder
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            If I run the tests from my host machine then WordPress root directory will be /Users/luca/Sites/wordpress, if I run the tests from within the Docker container then WordPress root folder will be /var/www/html.

                                                                                                                                                            +

                                                                                                                                                            Another example is Local by Flywheel:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • in the host machine the path to the WordPress root folder will be /Users/luca/Local\ Sites/wordpress/app/public
                                                                                                                                                            • +
                                                                                                                                                            • from within the Docker container managed by Local the path will be /app/public
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            If you need a solution that will work in both instances use a relative path: wp-browser will accept paths like ./../../../wordpress and will attempt to resolve them.

                                                                                                                                                            +

                                                                                                                                                            What is the path, relative to WordPress root URL, of the admin area of the test site?

                                                                                                                                                            +

                                                                                                                                                            This is usually /wp-admin but you might have the web-server, or a plugin, redirect or hide requests for the administration area to another path.

                                                                                                                                                            +

                                                                                                                                                            Some examples are /admin, /login and the like.

                                                                                                                                                            +

                                                                                                                                                            Mind that this is not the path to the login page but the path to the administrationo area; this will be used by wp-browser to find to the administration area in acceptance and functional tests.

                                                                                                                                                            +

                                                                                                                                                            What is the name of the test database used by the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's wordpress.

                                                                                                                                                            +

                                                                                                                                                            This is the name of the database that is storing the information used by the site I can reach at http://localhost:8080.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            I want to underline the word "test". Any site and any database you use and expose to wp-browser should be intended for tests; this means that it does not contain any data you care about as it will be lost.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            What is the host of the test database used by the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's 127.0.0.1:3306.

                                                                                                                                                            +

                                                                                                                                                            Here the same principle valid for Where is WordPress installed? applies: the database host is relative to the machine that is running the tests.

                                                                                                                                                            +

                                                                                                                                                            In my example I'm hosting the database locally, on my laptop, and my machine can reach it at the localhost address (127.0.0.1) on MySQL default port (3306).

                                                                                                                                                            +

                                                                                                                                                            If I am using the database of a Local by Flywheel site from my host machine then it might be something like 192.168.92.100:4050 (from the site "Database" tab); the same principle applies if I am using a Vagrant-based or Docker-based solution.

                                                                                                                                                            +

                                                                                                                                                            If I am running the tests from within a virtualized machine (a Docker container, a Vagrant box et cetera) then it would probably be localhost or 1270.0.0.1.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used in the context of acceptance and functional tests by the WPDb module.

                                                                                                                                                            +

                                                                                                                                                            What is the user of the test database used by the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's root as I'm using MySQL server root user to access the database during tests.

                                                                                                                                                            +

                                                                                                                                                            Depending on your setup it might be different; since wp-browser will need to not only read but write too to the database make sure to use a user that has full access to the database specified in the answer to the What is the host of the test database used by the test site? question.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used in the context of acceptance and functional tests by the WPDb module.

                                                                                                                                                            +

                                                                                                                                                            What is the password of the test database used by the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's empty as I've not set any password for the root account.

                                                                                                                                                            +

                                                                                                                                                            In your case it might be different and it should be the password associated with the user specified in the answer to the What is the user of the test database used by the test site? question.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used in the context of acceptance and functional tests by the WPDb module.

                                                                                                                                                            +

                                                                                                                                                            What is the table prefix of the test database used by the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's wp_; that value is taken from the WordPress installation configuration file.

                                                                                                                                                            +

                                                                                                                                                            To have any influence on the site wp-browser will need to modify the same database tables WordPress is using; as I did you can take this value from the wp-config.php file directly: it's the value of the $table_prefix variable.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used in the context of acceptance and functional tests by the WPDb module.

                                                                                                                                                            +

                                                                                                                                                            What is the name of the test database WPLoader should use?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's tests.

                                                                                                                                                            +

                                                                                                                                                            During integration, or WordPress "unit" tests, wp-loader will need to load WordPress code.

                                                                                                                                                            +

                                                                                                                                                            Since WordPress code is not meant to be "modular" it does not support auto-loading or loading just parts of it; it's either almost all or nothing.

                                                                                                                                                            +

                                                                                                                                                            One of the first things WordPress does, when loading, is trying to connect to a database: if that database is not available then WordPress will not load.

                                                                                                                                                            +

                                                                                                                                                            In the answer to the question Where is WordPress installed? I've told wp-browser where to find WordPress code, in this answer I'm telling wp-browser what database it should use to bootstrap WordPress.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress. +It's highly recommended to use a different database from the one used for functional and acceptance tests.

                                                                                                                                                            +

                                                                                                                                                            What is the host of the test database WPLoader should use?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's 127.0.0.1:3306.

                                                                                                                                                            +

                                                                                                                                                            As in the answer to the question What is the name of the test database WPLoader should use? we're providing connection details about the database that should be used to bootstrap WordPress during integration and WordPress "unit" tests.

                                                                                                                                                            +

                                                                                                                                                            Again the database host is in relation to the machine running the tests, all the considerations done for What is the host of the test database used by the test site? apply.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress.

                                                                                                                                                            +

                                                                                                                                                            What is the user of the test database WPLoader should use?

                                                                                                                                                            +

                                                                                                                                                            In my example it's root.

                                                                                                                                                            +

                                                                                                                                                            Similar to the question What is the user of the test database used by the test site? but in relation to the database specified in the question What is the name of the test database WPLoader should use?.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress.

                                                                                                                                                            +

                                                                                                                                                            What is the password of the test database WPLoader should use?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's empty as I've not set any password for the root account.

                                                                                                                                                            +

                                                                                                                                                            Similar to the question What is the password of the test database used by the test site? but in relation to the database specified in the question What is the name of the test database WPLoader should use?.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress.

                                                                                                                                                            +

                                                                                                                                                            What is the table prefix of the test database WPLoader should use?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's wp_.

                                                                                                                                                            +

                                                                                                                                                            Similar to the question What is the table prefix of the test database used by the test site? but in relation to the database specified in the question What is the name of the test database WPLoader should use?.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress.

                                                                                                                                                            +

                                                                                                                                                            What is the URL the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's http://localhost:8080.

                                                                                                                                                            +

                                                                                                                                                            This is the full URL you would have to enter in the browser, on the machine that is running the tests, to reach the test WordPress site homepage.

                                                                                                                                                            +

                                                                                                                                                            What is the email of the test site WordPress administrator?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's admin@wp.localhost.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and, while required, it's usually not relevant unless you're testing email communications.

                                                                                                                                                            +

                                                                                                                                                            What is the title of the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's Acme Plugin Test Site.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and, while required, it's usually not relevant unless you're testing around the site title.

                                                                                                                                                            +

                                                                                                                                                            What is the login of the administrator user of the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's admin.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPBrowser or WPWebDriver modules to fill in the login details for the administrator user.

                                                                                                                                                            +

                                                                                                                                                            It should be the same as the one that allows you to access the site administration area in the WordPress test site, http://localhost:8080/wp-admin in my example.

                                                                                                                                                            +

                                                                                                                                                            What is the password of the administrator user of the test site?

                                                                                                                                                            +

                                                                                                                                                            In my example setup it's password.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPBrowser or WPWebDriver modules to fill in the login details for the administrator user.

                                                                                                                                                            +

                                                                                                                                                            It should be the same as the one that allows you to access the site administration area in the WordPress test site, http://localhost:8080/wp-admin in my example.

                                                                                                                                                            +

                                                                                                                                                            Are you testing a plugin, a theme or a combination of both?

                                                                                                                                                            +

                                                                                                                                                            Depending on the answer the WPLoader module will load, during integration or WordPress "unit" tests, your WordPress plugin or theme.

                                                                                                                                                            +

                                                                                                                                                            If you replied with both (for "a combination of both") then you'll be able to choose the plugins and theme to load in integration and WordPress "unit" tests in the following questions.

                                                                                                                                                            +

                                                                                                                                                            What is the folder/plugin.php name of the plugin?

                                                                                                                                                            +

                                                                                                                                                            This question will be asked only if you replied plugin to the question Are you testing a plugin, a theme or a combination of both?.
                                                                                                                                                            +In my example setup it's acme-plugin/plugin.php.

                                                                                                                                                            +

                                                                                                                                                            This is the <folder>/<main-plugin-file>.php path, relative to the WordPress installation plugins folder, to the plugin you are testing.

                                                                                                                                                            +

                                                                                                                                                            The main plugin file is the one that contains the plugin header.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and load your plugin or theme in integration and WordPress "unit" tests.

                                                                                                                                                            +

                                                                                                                                                            Are you developing a child theme?

                                                                                                                                                            +

                                                                                                                                                            This question will be asked only if you replied theme to the question Are you testing a plugin, a theme or a combination of both?.
                                                                                                                                                            +Enter yes if you are developing a child theme.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and load a parent theme along with your theme in integration and WordPress "unit" tests.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Please note that wp-browser will not download and install the parent theme in the WordPress installation for you.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Are you using a child theme?

                                                                                                                                                            +

                                                                                                                                                            This question will be asked only if you replied both to the question Are you testing a plugin, a theme or a combination of both?.
                                                                                                                                                            +Enter yes if you are using a child theme.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and load a parent theme along with your theme in integration and WordPress "unit" tests.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Please note that wp-browser will not download and install the parent theme in the WordPress installation for you.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            What is the slug of the parent theme?

                                                                                                                                                            +

                                                                                                                                                            This question will be asked only if you replied yes to the question Are you developing a child theme?.

                                                                                                                                                            +

                                                                                                                                                            Reply with the slug of the parent theme, that's usually the name of the folder the parent theme lives in, e.g. twentyseventeen.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and load a parent theme along with your theme in integration and WordPress "unit" tests.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Please note that wp-browser will not download and install the parent theme in the WordPress installation for you.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            What is the slug of the theme?

                                                                                                                                                            +

                                                                                                                                                            This question will be asked only if you replied theme to the question Are you testing a plugin, a theme or a combination of both?.
                                                                                                                                                            +Reply with the slug of the theme, that's usually the name of the folder the theme lives in, e.g. twentyseventeen.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and load your theme in integration and WordPress "unit" tests.

                                                                                                                                                            +

                                                                                                                                                            What is the slug of the theme you are using?

                                                                                                                                                            +

                                                                                                                                                            This question will be asked only if you replied both to the question Are you testing a plugin, a theme or a combination of both?.
                                                                                                                                                            +Reply with the slug of the theme you are using, that's usually the name of the folder the theme lives in, e.g. twentyseventeen.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and load the theme integration and WordPress "unit" tests.

                                                                                                                                                            +

                                                                                                                                                            Does your project needs additional plugins to be activated to work?

                                                                                                                                                            +

                                                                                                                                                            Whether you're testing a plugin, a theme or a combination of both you might need some additional plugins to run your tests.

                                                                                                                                                            +

                                                                                                                                                            As an example if I'm testing a WooCommerce extension I need the WooCommerce plugin to test it; this is the place where I can define it.

                                                                                                                                                            +

                                                                                                                                                            The required plugins follow the same format as the one used in the question What is the folder/plugin.php name of the plugin?: <plugin-folder>/<plugin-main-file>.php; in the case of WooCommerce it would be woocommerce/woocommerce.php.

                                                                                                                                                            +

                                                                                                                                                            This detail will be used by the WPLoader module to bootstrap WordPress and load the required plugins in integration and WordPress "unit" tests.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Please note that wp-browser will not download and install the required plugins in the WordPress installation for you.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If you entered a wrong value

                                                                                                                                                            +

                                                                                                                                                            No worries, just correct the value in the environment file or in the suites configuration files.

                                                                                                                                                            +

                                                                                                                                                            The environment file will have the name you specified in the answer the question How would you like to call the env configuration file?.

                                                                                                                                                            +

                                                                                                                                                            The suites configuration files can be found in tests/<suite>.suite.yml; e.g. the wpunit suite configuration file will be tests/wpunit.suite.yml file.

                                                                                                                                                            +

                                                                                                                                                            Final steps

                                                                                                                                                            +

                                                                                                                                                            To complete the setup I have removed any demo content from the site and activated my plugin in the plugins administration page.

                                                                                                                                                            +

                                                                                                                                                            In the tests/acceptance.suite.yml file and in the tests/functional.suite.yml file, the configuration file for the acceptance and functional suites respectively, the WPDb module configuration contains a dump configuration parameter:

                                                                                                                                                            +
                                                                                                                                                            class_name: AcceptanceTester
                                                                                                                                                            +modules:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - WPDb
                                                                                                                                                            +    config:
                                                                                                                                                            +        WPDb:
                                                                                                                                                            +            dump: 'tests/_data/dump.sql'
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The dump parameter is inherited by the WPDb module from the Codeception Db module and defines the SQL dump file that should be loaded before, and between, tests to reset the testing environment to a base known state.

                                                                                                                                                            +

                                                                                                                                                            As for any other database-related operation wp-browser will not create the dump for me. +I use MySQL binary to export the database state (a dump) with the command:

                                                                                                                                                            +
                                                                                                                                                            mysqldump -u root -h 127.0.0.1 -P 3306 wordpress > /Users/luca/Sites/wordpress/wp-content/plugins/acme-plugin/tests/_data/dump.sql
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            I could use any other combination of tools to produce the dump; using mysql binary is not a requirement.

                                                                                                                                                            +

                                                                                                                                                            Graphic interfaces like SequelPro, Adminer and the like would be perfectly fine.

                                                                                                                                                            +

                                                                                                                                                            Pre-flight check

                                                                                                                                                            +

                                                                                                                                                            There is one last check I need to make before jumping into the creation of tests: making sure all the paths and credentials I've configured wp-browser with are correct.

                                                                                                                                                            +

                                                                                                                                                            The bootstrap process generated four suites for me: acceptance, functional, integration and unit. If you have modified the default suite names during the setup your suites names might differ though.

                                                                                                                                                            +

                                                                                                                                                            To test the setup I will run each suite and make sure it can run correctly empty of any test. To run a suite of tests I will use the codecept run command:

                                                                                                                                                            +
                                                                                                                                                            codecept run acceptance
                                                                                                                                                            +codecept run functional
                                                                                                                                                            +codecept run integration
                                                                                                                                                            +codecept run unit
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            How comes I'm not using the command codecept run (without specifying the suite names)? See the FAQ entry.

                                                                                                                                                            +

                                                                                                                                                            Pre-flight check

                                                                                                                                                            +

                                                                                                                                                            If you cannot run all the suites without issues then check your configuration settings again, read the errors and see If you entered a wrong value

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/events-api/index.html b/v3/events-api/index.html new file mode 100644 index 000000000..813dcd87b --- /dev/null +++ b/v3/events-api/index.html @@ -0,0 +1,3055 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Events API - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Events API

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Events API

                                                                                                                                                            +

                                                                                                                                                            Codeception comes with a set of events modules and extensions can subscribe to.

                                                                                                                                                            +

                                                                                                                                                            Codeception Events API is, but, only available to Modules and Extensions, and while that might be good for most cases, it might not cover a number of edge cases.

                                                                                                                                                            +

                                                                                                                                                            Similarly to WordPress add_action function, wp-browser provides the tad\WPBrowser\addListener function:

                                                                                                                                                            +
                                                                                                                                                            function addListener($eventName, callable $listener, $priority = 0);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The priority works the reverse way as it does in WordPress: highest number will be processed first!

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Again similarly to WordPress do_action function, the tad\WPBrowser\dispatch function:

                                                                                                                                                            +
                                                                                                                                                            function dispatch($eventName, $origin = null, array $context = []);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This is the kind of API that is better shown with an example, though.

                                                                                                                                                            +

                                                                                                                                                            Example

                                                                                                                                                            +

                                                                                                                                                            In this example I'm writing acceptance tests and would like to avoid the performance hit that the cleanup configuration parameter of the Db, or WPDb, module implies.
                                                                                                                                                            +The cleanup parameter will trigger the drop of all tables in the test database and the re-import of the SQL dump file, or files, between each test.
                                                                                                                                                            +This will ensure a clean starting fixture between tests, but for larger setup fixtures this might be a long operation that wastes precious seconds when, say, the only change is the addition of 3 posts, as in this example.

                                                                                                                                                            +

                                                                                                                                                            The Events API allows implementing a tailored clean-up procedure that can avoid costly clean ups between tests.

                                                                                                                                                            +

                                                                                                                                                            In the suite bootstrap file, e.g. tests/acceptance/_bootstrap.php, I add a listener on the my-plugin-test/setup-posts event.
                                                                                                                                                            +The event will contain information about what post IDs I've set up in the tests and will provide an instance of the tester object to handle database manipulation.
                                                                                                                                                            +With that information, the costly cleanup procedure can be avoided.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +$registerPostsCleanup = static function (tad\WPBrowser\Events\WpbrowserEvent $event) {
                                                                                                                                                            +    $ids = $event->get('ids', []);
                                                                                                                                                            +    /** @var \EventsTester $db */
                                                                                                                                                            +    $db = $event->get('db');
                                                                                                                                                            +
                                                                                                                                                            +    // When tests are done, then remove all the posts we've created at the start of the test, if any.
                                                                                                                                                            +    tad\WPBrowser\addListener(
                                                                                                                                                            +        Codeception\Events::TEST_AFTER,
                                                                                                                                                            +        static function () use ($ids, $db) {
                                                                                                                                                            +            foreach ($ids as $id) {
                                                                                                                                                            +                $db->dontHavePostInDatabase([ 'ID' => $id ], true);
                                                                                                                                                            +                // Ensure the clean up did happen correctly.
                                                                                                                                                            +                $db->dontSeePostInDatabase([ 'ID' => $id ]);
                                                                                                                                                            +                $db->dontSeePostMetaInDatabase([ 'post_id' => $id ]);
                                                                                                                                                            +            }
                                                                                                                                                            +        }
                                                                                                                                                            +    );
                                                                                                                                                            +};
                                                                                                                                                            +
                                                                                                                                                            +// Listen for this event to register the posts to remove, along with their custom fields, after the test.
                                                                                                                                                            +tad\WPBrowser\addListener('test-event-1/setup-posts', $registerPostsCleanup);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            In this simple test I'm adding 3 posts [using the factory provided by the WPLoader module in loadOnly mode][2] and want to make sure those, and the relative meta, are removed at the end of the tests. +The WPDb module, extending the Db module from Codeception, will remove the inserted rows, but will not take care of modified rows, or rows not inserted by the WPDb module.

                                                                                                                                                            +

                                                                                                                                                            Mirroring the requirement of the clean up function I've defined above, I'm passing the post IDs of the posts I've created and the current tester to provide the clean up function with database handling capabilities.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +/** @var Codeception\Scenario $scenario */
                                                                                                                                                            +$I = new AcceptanceTester($scenario);
                                                                                                                                                            +$I->wantTo('add posts and clean them up using the Events API');
                                                                                                                                                            +
                                                                                                                                                            +/*
                                                                                                                                                            + * Use WordPress methods, thanks to the `WPLoader` module, to use WordPress, or our own, API to insert posts.
                                                                                                                                                            + * This will prevent, but, `WPDb` from removing the inserted rows and clean up, so we remove the posts and meta
                                                                                                                                                            + * with an event and our custom clean-up function.
                                                                                                                                                            + */
                                                                                                                                                            +$ids = $I->factory()->post->create_many(3, [ 'post_type' => 'some_post_type' ]);
                                                                                                                                                            +
                                                                                                                                                            +tad\WPBrowser\dispatch('test-event-1/setup-posts', __FILE__, [
                                                                                                                                                            +    'ids' => $ids,
                                                                                                                                                            +    'db'  => $I
                                                                                                                                                            +]);
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/extensions/index.html b/v3/extensions/index.html new file mode 100644 index 000000000..c1bc2576f --- /dev/null +++ b/v3/extensions/index.html @@ -0,0 +1,3171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Extensions - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Extensions

                                                                                                                                                            +

                                                                                                                                                            The Codeception testing framework can be extended in a number of ways.

                                                                                                                                                            +

                                                                                                                                                            The one this project leverages the most are modules but [extensions are another way].

                                                                                                                                                            +

                                                                                                                                                            Modules extend the functionality of Codeception in the context of the tests, while extensions extend its interaction capacities; this is by no means a strict rule but that's usually the case.

                                                                                                                                                            +

                                                                                                                                                            The package contains two additional extensions to facilitate testers' life.

                                                                                                                                                            +

                                                                                                                                                            Symlinker

                                                                                                                                                            +

                                                                                                                                                            The tad\WPBrowser\Extension\Symlinker extension provides an automation to have the Codeception root directory symbolically linked in a WordPress local installation.

                                                                                                                                                            +

                                                                                                                                                            Since version 3.9 WordPress supports this feature (with some precautions) and the extension takes charge of:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • symbolically linking a plugin or theme folder in the specified destination before any suite boots up
                                                                                                                                                            • +
                                                                                                                                                            • unlinking that symbolic link after all of the suites did run
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            It's the equivalent of doing something like this from the command line (on a Mac):

                                                                                                                                                            +
                                                                                                                                                            ln -s /my/central/plugin/folder/my-plugin /my/local/wordpress/installation/wp-content/plugins/my-plugin
                                                                                                                                                            +/my/central/plugin/folder/my-plugin/vendor/bin/codecept run
                                                                                                                                                            +rm -rf /my/local/wordpress/installation/wp-content/plugins/my-plugin
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The extension needs small configuration in the codeception.yml file:

                                                                                                                                                            +
                                                                                                                                                            extensions:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - tad\WPBrowser\Extension\Symlinker
                                                                                                                                                            +    config:
                                                                                                                                                            +        tad\WPBrowser\Extension\Symlinker:
                                                                                                                                                            +            mode: plugin
                                                                                                                                                            +            destination: /my/local/wordpress/installation/wp-content/plugins
                                                                                                                                                            +            rootFolder: /some/plugin/folder
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The arguments are:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • mode - can be plugin or theme and indicates whether the current Codeception root folder being symlinked is a plugin or a theme one
                                                                                                                                                            • +
                                                                                                                                                            • destination - the absolute path to the WordPress local installation plugins or themes folder; to take the never ending variety of possible setups into account the extension will make no checks on the nature of the destination: could be any folder.
                                                                                                                                                            • +
                                                                                                                                                            • rootFolder - optional absolute path to the WordPress plugin or theme to be symlinked root folder; will default to the Codeception root folder
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Copier

                                                                                                                                                            +

                                                                                                                                                            The tad\WPBrowser\Extension\Copier extension provides an automation to have specific files and folders copied to specified destination files and folders before the suites run.

                                                                                                                                                            +

                                                                                                                                                            While WordPress handles symbolic linking pretty well there are some cases, like themes and drop-ins, where there is a need for "real" files to be put in place.

                                                                                                                                                            +

                                                                                                                                                            One of such cases is, currently, one where Docker is used to to host and serve the code under test: symbolically linked files cannot be bound inside a container and Docker containers will fail to start in this case.

                                                                                                                                                            +

                                                                                                                                                            The extension follows the standard Codeception extension activation and has one configuration parameter only:

                                                                                                                                                            +
                                                                                                                                                            extensions:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - tad\WPBrowser\Extension\Copier
                                                                                                                                                            +    config:
                                                                                                                                                            +        tad\WPBrowser\Extension\Copier:
                                                                                                                                                            +            files:
                                                                                                                                                            +                tests/_data/required-drop-in.php: /var/www/wordpress/wp-content/drop-in.php
                                                                                                                                                            +                tests/_data/themes/dummy: /var/www/wordpress/wp-content/themes/dummy
                                                                                                                                                            +                /Users/Me/Repos/required-plugin: /var/www/wordpress/wp-content/plugins/required-plugin.php
                                                                                                                                                            +                /Users/Me/Repos/mu-plugin.php: ../../../../wp-content/mu-plugins/mu-plugin.php
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The extension will handle absolute and relative paths for sources and destinations and will resolve relative paths from the project root folder.

                                                                                                                                                            +

                                                                                                                                                            When copying directories the extension will only create the destination folder and not the folder tree required; in the example configuration above the last entry specifies that a mu-plugin.php file should be copied to the mu-plugins folder: that mu-plugins folder must be there already.

                                                                                                                                                            +

                                                                                                                                                            Environments support

                                                                                                                                                            +

                                                                                                                                                            Being able to symlink a plugin or theme folder into a WordPress installation for testing purposes could make sense when trying to test, as an example, a plugin in a single site and in multi site environment.

                                                                                                                                                            +

                                                                                                                                                            Codeception supports environments and the extension does as well specifying a destination for each.

                                                                                                                                                            +

                                                                                                                                                            As an example the acceptance.suite.yml file might be configured to support single and multisite environments:

                                                                                                                                                            +
                                                                                                                                                            env:
                                                                                                                                                            +    single:
                                                                                                                                                            +        modules:
                                                                                                                                                            +            config:
                                                                                                                                                            +                WPBrowser:
                                                                                                                                                            +                    url: 'http://wp.dev'
                                                                                                                                                            +                WPDb:
                                                                                                                                                            +                    dsn: 'mysql:host=127.0.0.1;dbname=wp'
                                                                                                                                                            +    multisite:
                                                                                                                                                            +        modules:
                                                                                                                                                            +            config:
                                                                                                                                                            +                WPBrowser:
                                                                                                                                                            +                    url: 'http://mu.dev'
                                                                                                                                                            +                WPDb:
                                                                                                                                                            +                    dsn: 'mysql:host=127.0.0.1;dbname=mu'
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            In the codeception.yml file specifying a destination for each supported environment will tell the extension to symbolically link the plugin or theme file to different locations according to the current environment:

                                                                                                                                                            +
                                                                                                                                                            extensions:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - tad\WPBrowser\Extension\Symlinker
                                                                                                                                                            +    config:
                                                                                                                                                            +        tad\WPBrowser\Extension\Symlinker:
                                                                                                                                                            +            mode: plugin
                                                                                                                                                            +            destination:
                                                                                                                                                            +                single: /var/www/wp/wp-content/plugins
                                                                                                                                                            +                multisite: /var/www/mu/wp-content/plugins
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If no destination is specified for the current environment the extension will fallback to the first specified one.

                                                                                                                                                            +

                                                                                                                                                            A default destination can be specified to override this behaviour.

                                                                                                                                                            +
                                                                                                                                                            extensions:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - tad\WPBrowser\Extension\Symlinker
                                                                                                                                                            +    config:
                                                                                                                                                            +        tad\WPBrowser\Extension\Symlinker:
                                                                                                                                                            +            mode: plugin
                                                                                                                                                            +            destination:
                                                                                                                                                            +                default: /var/www/default/wp-content/plugins
                                                                                                                                                            +                single: /var/www/wp/wp-content/plugins
                                                                                                                                                            +                multisite: /var/www/mu/wp-content/plugins
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            When running a suite specifying more than one environment like

                                                                                                                                                            +
                                                                                                                                                            codecept run acceptance --env foo,baz,multisite
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Then the extension will use the first matched one, in the case above the multisite destination will be used.

                                                                                                                                                            +

                                                                                                                                                            The rootFolder parameter too can be set to be environment-aware and it will follow the same logic as the destination:

                                                                                                                                                            +
                                                                                                                                                            extensions:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - tad\WPBrowser\Extension\Symlinker
                                                                                                                                                            +    config:
                                                                                                                                                            +        tad\WPBrowser\Extension\Symlinker:
                                                                                                                                                            +            mode: plugin
                                                                                                                                                            +            rootFolder:
                                                                                                                                                            +                dev: /
                                                                                                                                                            +                dist: /dist
                                                                                                                                                            +                default: /
                                                                                                                                                            +            destination:
                                                                                                                                                            +                default: /var/www/dev/wp-content/plugins
                                                                                                                                                            +                dev: /var/www/dev/wp-content/plugins
                                                                                                                                                            +                dist: /var/www/dist/wp-content/plugins
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            When running a suite specifying more than one environment like

                                                                                                                                                            +
                                                                                                                                                            codecept run acceptance --env dist
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Then the extension will symlink the files from /dist into the /var/www/dist/wp-content/plugins folder.

                                                                                                                                                            +

                                                                                                                                                            Events

                                                                                                                                                            +

                                                                                                                                                            Due to some internal changes in Codeception 4.0, the internal API (really a collection of low-level hacks on my part) that allowed wp-browser to dispatch, and listen for, events in the modules has been removed.

                                                                                                                                                            +

                                                                                                                                                            If you want to leverage [the event system wp-browser provides] with Codeception default events (e.g. suite.init or test.before), then you will need to use this extension.

                                                                                                                                                            +

                                                                                                                                                            You will not need this extension if you're not using Codeception version 4.0.

                                                                                                                                                            +

                                                                                                                                                            You will need to enable it in your Codeception main configuration file (e.g. codeception.dist.yml).

                                                                                                                                                            +
                                                                                                                                                            extensions:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - tad\WPBrowser\Extension\Events
                                                                                                                                                            +    config:
                                                                                                                                                            +      tad\WPBrowser\Extension\Events:
                                                                                                                                                            +        suites: ['acceptance']
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The extension only configuration is the suites parameter that allows specifying the suites the extension should apply to.
                                                                                                                                                            +If the suites parameter is not specified, then the extension will apply to all suites.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/faq/index.html b/v3/faq/index.html new file mode 100644 index 000000000..a55e525d0 --- /dev/null +++ b/v3/faq/index.html @@ -0,0 +1,3333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Frequently asked questions - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Frequently asked questions

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Some common questions

                                                                                                                                                            +

                                                                                                                                                            There are questions I keep receiving via email, GitHub or in person at conferences.

                                                                                                                                                            +

                                                                                                                                                            I tried to address some of them here.

                                                                                                                                                            +

                                                                                                                                                            Is Codeception/wp-browser PHP 5.2 compatible?

                                                                                                                                                            +

                                                                                                                                                            No, Codeception, and wp-browser by extension, will require PHP 5.6 minimum.

                                                                                                                                                            +

                                                                                                                                                            This does not mean your code cannot be PHP 5.2 compatible: you can test your code using all the possibilities of newer PHP versions and still keep it PHP 5.2 compatible.

                                                                                                                                                            +

                                                                                                                                                            Just because you can doesn't mean you should though: this documentation will assume a minimum PHP version, for the example and test code, of PHP 5.6.

                                                                                                                                                            +

                                                                                                                                                            Can I run unit tests with wp-browser/Codeception?

                                                                                                                                                            +

                                                                                                                                                            Yes, with some distinctions.

                                                                                                                                                            +

                                                                                                                                                            In the WordPress ecosystem there's a tendency to call any kind of test a "unit test". Under that definition will fall tests that are not "unit" tests at all.

                                                                                                                                                            +

                                                                                                                                                            Without drowning into a long and painful battle for definitions this guide will use the following definitions for different levels of testing.

                                                                                                                                                            +

                                                                                                                                                            The next section will detail the conventions this documentation uses to define different levels of testing in more detail.

                                                                                                                                                            +

                                                                                                                                                            Isn't WordPress untestable?

                                                                                                                                                            +

                                                                                                                                                            No; it's sometimes difficult to test and not as straightforward as other PHP frameworks but it's definitely not untestable.

                                                                                                                                                            +

                                                                                                                                                            You are writing code that runs on WordPress, not the Core code for WordPress so the question should really be: will you write testable code?

                                                                                                                                                            +

                                                                                                                                                            It's up to you to decide at what level you want to make your code testable and how much you want to test it.

                                                                                                                                                            +

                                                                                                                                                            Do I need to use a specific local development environment to use wp-browser?

                                                                                                                                                            +

                                                                                                                                                            No. I've started using wp-browser on a vanilla PHP built-in server to, then, move to MAMP (or XAMP) and, from there, to other solutions.

                                                                                                                                                            +

                                                                                                                                                            I've configured and used wp-browser on Docker, Vagrant, VVV, Valet and various CI solutions.

                                                                                                                                                            +

                                                                                                                                                            To this day I keep using different setups on different machines and personally prefer Docker for its portability.

                                                                                                                                                            +

                                                                                                                                                            Can I only test plugins with wp-browser?

                                                                                                                                                            +

                                                                                                                                                            No, you can test any kind of WordPress application.

                                                                                                                                                            +

                                                                                                                                                            With "application" I mean any PHP software built on top of WordPress: plugins, themes, whole sites.

                                                                                                                                                            +

                                                                                                                                                            If I'm testing a site do I have to use the default WordPress file structure?

                                                                                                                                                            +

                                                                                                                                                            No, you can use any file structure you want.

                                                                                                                                                            +

                                                                                                                                                            Some wp-browser modules will need a little help to find your code but, so far, I've never been unable to set it up.

                                                                                                                                                            +

                                                                                                                                                            Can I use wp-browser even if my WordPress application doesn't use Composer?

                                                                                                                                                            +

                                                                                                                                                            Yes, although wp-browser, as a development tool, cannot be installed without Composer.

                                                                                                                                                            +

                                                                                                                                                            Should I use wp-browser to test my production servers?

                                                                                                                                                            +

                                                                                                                                                            No. Unless you know very well what you're doing that's a dangerous idea that might leave you with a broken site and an empty database.

                                                                                                                                                            +

                                                                                                                                                            As almost any testing tool, wp-browser should be used locally on local installations of WordPress that do not contain any valuable information.

                                                                                                                                                            +

                                                                                                                                                            How can I avoid the WPDb module from replacing the contents of my database?

                                                                                                                                                            +

                                                                                                                                                            You should always backup any database that contains any information you care about before running any test.

                                                                                                                                                            +

                                                                                                                                                            You can read the answer to this question in the WPDb module documentation.

                                                                                                                                                            +

                                                                                                                                                            Can I run all my tests with one command?

                                                                                                                                                            +

                                                                                                                                                            Theoretically: yes, in practice: no.

                                                                                                                                                            +

                                                                                                                                                            When you use codecept run Codeception will run all the tests from all the suites.

                                                                                                                                                            +

                                                                                                                                                            This, done in the context of other frameworks, will generally not create any problem but, in the context of WordPress it will.

                                                                                                                                                            +

                                                                                                                                                            While handling a single HTTP request WordPress will set, and use, a number of constants and globals and, likewise, will do plugins and themes that follow WordPress standards.

                                                                                                                                                            +

                                                                                                                                                            This means that the global context (variable scope) will be left "dirty" and contain "left-over" constants and globals from the previous tests.

                                                                                                                                                            +

                                                                                                                                                            An example is one where a test for the handling of Ajax requests sets the DOING_AJAX constant: this will be now set for any test after the one that set it thus breaking, or worse altering, all the following ones.

                                                                                                                                                            +

                                                                                                                                                            So, in short, run each suite separately.

                                                                                                                                                            +

                                                                                                                                                            Can I have more than one suite of one kind?

                                                                                                                                                            +

                                                                                                                                                            Yes, you should.

                                                                                                                                                            +

                                                                                                                                                            As an example you might have a frontend suite running acceptance tests on the site frontend and a backend suite running acceptance tests on the site backend.

                                                                                                                                                            +

                                                                                                                                                            Think of suites as a tool to organize your tests: there's a good measure between too organized and not organized at all.

                                                                                                                                                            +

                                                                                                                                                            I've used PHPUnit before for my unit tests, can I reuse that knowledge and code with wp-browser?

                                                                                                                                                            +

                                                                                                                                                            Yes.

                                                                                                                                                            +

                                                                                                                                                            Codeception uses PHPUnit as one of its main components and can run PHPUnit tests with little or no modification.

                                                                                                                                                            +

                                                                                                                                                            As such you can just move your existing PHPUnit tests in a dedicated suite and be ready to run in minutes.

                                                                                                                                                            +

                                                                                                                                                            I've already set up my tests to run using the Core PHPUnit-based test suite, can I keep using my tests?

                                                                                                                                                            +

                                                                                                                                                            Yes.

                                                                                                                                                            +

                                                                                                                                                            Codeception uses PHPUnit as one of its main components and can run PHPUnit tests with little or no modification.

                                                                                                                                                            +

                                                                                                                                                            One of the goals of wp-browser was to make it easier to test WordPress application at an integration level (or "WordPress unit" level).

                                                                                                                                                            +

                                                                                                                                                            As such migrating those tests could be a matter of minutes requiring no modification to the tests if not for moving some files and creating a dedicated suite.

                                                                                                                                                            +

                                                                                                                                                            Why is the project called wp-browser?

                                                                                                                                                            +

                                                                                                                                                            When I started working with Codeception to run my acceptance tests I kept creating steps that I would reuse over and over in my projects.

                                                                                                                                                            +

                                                                                                                                                            I packed them in a module extending the PHPBrowser module.

                                                                                                                                                            +

                                                                                                                                                            Being a natural talent in naming things I've called the module WPBrowser and published it. As I started relying on Codeception more and more I kept adding modules but the name remained.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/images/codecept-init-wpbrowser-01.png b/v3/images/codecept-init-wpbrowser-01.png new file mode 100644 index 000000000..688a58098 Binary files /dev/null and b/v3/images/codecept-init-wpbrowser-01.png differ diff --git a/v3/images/codecept-init-wpbrowser-02.png b/v3/images/codecept-init-wpbrowser-02.png new file mode 100644 index 000000000..c2b9dcb5d Binary files /dev/null and b/v3/images/codecept-init-wpbrowser-02.png differ diff --git a/v3/images/codecept-run.png b/v3/images/codecept-run.png new file mode 100644 index 000000000..000ff012b Binary files /dev/null and b/v3/images/codecept-run.png differ diff --git a/v3/images/initial-setup.png b/v3/images/initial-setup.png new file mode 100644 index 000000000..c0e32e416 Binary files /dev/null and b/v3/images/initial-setup.png differ diff --git a/v3/index.html b/v3/index.html new file mode 100644 index 000000000..9348668d2 --- /dev/null +++ b/v3/index.html @@ -0,0 +1,2889 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Welcome - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Welcome

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The wp-browser project provides a Codeception based solution to test WordPress plugins, themes and whole sites at all levels of testing.

                                                                                                                                                            +

                                                                                                                                                            The purpose of this documentation is to help you set up, run and iterate over your project and test code using the powerful APIs provided by Codeception while trying to alleviate the pains of setting it up for WordPress projects.

                                                                                                                                                            +

                                                                                                                                                            Throughout the documentation you will find references to test terminology: I've tried to condense those into small, digestable chunks to provide a rough idea without and a limited context; where required I tried to provide links to dive deeper into the subjects.

                                                                                                                                                            +

                                                                                                                                                            Happy testing!

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/installation/index.html b/v3/installation/index.html new file mode 100644 index 000000000..850114379 --- /dev/null +++ b/v3/installation/index.html @@ -0,0 +1,3059 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Installation - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Installation

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Installation

                                                                                                                                                            +

                                                                                                                                                            Where should I install wp-browser?

                                                                                                                                                            +

                                                                                                                                                            As a rule-of-thumb wp-browser should be installed in the root folder of your +project.

                                                                                                                                                            +

                                                                                                                                                            If your project is a plugin then it should be installed in the root folder of your plugin; if your project is a theme it should be installed in the root folder of your theme.

                                                                                                                                                            +

                                                                                                                                                            If your project is a site I'd, personally install it in the site root folder.

                                                                                                                                                            +

                                                                                                                                                            The purpose of installing wp-browser in the root folder of a project is to keep the code and its tests under version control together.

                                                                                                                                                            +

                                                                                                                                                            Exceptions apply but, for most projects, that's what I would do.

                                                                                                                                                            +

                                                                                                                                                            Initializing the Composer project

                                                                                                                                                            +

                                                                                                                                                            Since Composer is a requirement of wp-browser and the only way to install it you should, first thing, initialize the Composer project.

                                                                                                                                                            +

                                                                                                                                                            If you've already initialized the Composer project you can skip this section.

                                                                                                                                                            +

                                                                                                                                                            Once you've decided where to install wp-browser navigate to that folder using the terminal and type:

                                                                                                                                                            +
                                                                                                                                                            composer init
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Composer will take you through a number of questions to setup some meta information about your project.

                                                                                                                                                            +

                                                                                                                                                            Do not install any dependency yet when asked (unless you know what you're doing) and, as a suggestion, set wordpress-plugin as "Package Type".

                                                                                                                                                            +

                                                                                                                                                            Also, since WordPress is licensed under the GPL-2.0+ you might want to set the "License" of your project to GPL-2.0-or-later.

                                                                                                                                                            +

                                                                                                                                                            Installing wp-browser as a development dependency

                                                                                                                                                            +

                                                                                                                                                            Once you've initialized the Composer project it's time to require wp-browser ; you can read more about the usage of the require command on the Composer documentation.

                                                                                                                                                            +

                                                                                                                                                            wp-browser is a testing tool and, as such, should be installed as a project development dependency, not as a normal (production) one.

                                                                                                                                                            +

                                                                                                                                                            From the terminal type:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev lucatume/wp-browser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This will install the latest stable version of wp-browser and, along with it, Codeception and PHPUnit in the vendor folder of your project.

                                                                                                                                                            +

                                                                                                                                                            Once that's done it's time to move to the setup and configuration of wp-browser.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/levels-of-testing/index.html b/v3/levels-of-testing/index.html new file mode 100644 index 000000000..62de7b38b --- /dev/null +++ b/v3/levels-of-testing/index.html @@ -0,0 +1,3329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Levels of testing - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Levels of testing

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            What is a unit test? An acceptance test?

                                                                                                                                                            +

                                                                                                                                                            This page has no pretense to be THE source of truth about what is called how in the context of tests; the purpose of this page is to lay out the terminology that I'll use in the documentation to define the levels and component of testing. Wikipedia, forums and other documents online will offer alternate, and equally valid, definitions.

                                                                                                                                                            +

                                                                                                                                                            The signup page example

                                                                                                                                                            +

                                                                                                                                                            Let's assume I'm testing a WordPress plugin that adds mailing list management and subscription functionalities to a site.

                                                                                                                                                            +

                                                                                                                                                            The plugin provides a number of functions and, among them, it will add a sign-up page to receive users applications.

                                                                                                                                                            +

                                                                                                                                                            Acceptance tests

                                                                                                                                                            +

                                                                                                                                                            In brief: make assertions as a user would.

                                                                                                                                                            +

                                                                                                                                                            The user might be tech-savvy as much as I want her to be but still make assertions only on what feedback the site provides.

                                                                                                                                                            +

                                                                                                                                                            The code below tests a user can subscribe to the mailing list:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// UserSuccessfulSignupTest.php
                                                                                                                                                            +
                                                                                                                                                            +// Add a page that contains the shortcode that will render the signup form.
                                                                                                                                                            +$I->havePageInDatabase( [
                                                                                                                                                            +    'post_name' => 'signup',
                                                                                                                                                            +    'post_content'=> 'Sign-up for our awesome thing! [signup]',
                                                                                                                                                            +] );
                                                                                                                                                            +
                                                                                                                                                            +// Go to the page.
                                                                                                                                                            +$I->amOnPage( '/signup' );
                                                                                                                                                            +
                                                                                                                                                            +// Submit the form as a user would submit it. 
                                                                                                                                                            +$I->submitForm( '#signup-form', [
                                                                                                                                                            +  'name' => 'Luca',
                                                                                                                                                            +  'email' => 'luca@theAverageDev.com',
                                                                                                                                                            +] );
                                                                                                                                                            +
                                                                                                                                                            +// Make sure I see a confirmation message. 
                                                                                                                                                            +$I->waitForElement( '#signup-confirmation' );
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Functional tests

                                                                                                                                                            +

                                                                                                                                                            In brief: make assertions as a developer would.

                                                                                                                                                            +

                                                                                                                                                            The test code below asserts front-end submissions are correctly processed from the developer perspective:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// file tests/functional/SignupSubmissionCest.php
                                                                                                                                                            +
                                                                                                                                                            +class SignupSubmissionCest {
                                                                                                                                                            +
                                                                                                                                                            +    public function _before( FunctionalTester $I ) {
                                                                                                                                                            +        // Add a page that contains the shortcode that will render the signup form.
                                                                                                                                                            +        $I->havePageInDatabase( [
                                                                                                                                                            +            'post_name' => 'signup',
                                                                                                                                                            +            'post_content'=> 'Sign-up for our awesome thing! [signup]',
                                                                                                                                                            +        ] );
                                                                                                                                                            +
                                                                                                                                                            +        $I->amOnPage( '/signup' );
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_good_signup( FunctionalTester $I ) {
                                                                                                                                                            +        $I->sendAjaxPostRequest( '/wp-json/acme/v1/signup', [
                                                                                                                                                            +          '_wpnonce' => $I->grabAttributeFrom( '#signup-nonce', 'value' ),
                                                                                                                                                            +          'name' => 'Luca',
                                                                                                                                                            +          'email' => 'luca@theAverageDev.com',
                                                                                                                                                            +        ] );
                                                                                                                                                            +
                                                                                                                                                            +        $I->seeResponseCodeIsSuccessful();
                                                                                                                                                            +        $I->seeUserInDatabase( [ 'user_login' => 'luca', 'user_email' => 'luca@theaveragedev.com' ] );
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_bad_email_signup( FunctionalTester $I ) {
                                                                                                                                                            +        $I->sendAjaxPostRequest( '/wp-json/acme/v1/signup', [
                                                                                                                                                            +          '_wpnonce' => $I->grabAttributeFrom( '#signup-nonce', 'value' ),
                                                                                                                                                            +          'name' => 'Luca',
                                                                                                                                                            +          'email' => 'not-really-an-email',
                                                                                                                                                            +        ] );
                                                                                                                                                            +
                                                                                                                                                            +        $I->seeResponseCodeIs( 400 );
                                                                                                                                                            +        $I->dontSeeUserInDatabase( [ 'user_login' => 'luca', 'user_email' => 'not-really-an-email' ] );
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The code looks, initially, like an acceptance test, but differs in its action and assertion phase: in place of filling a form and clicking "Submit" it sends a POST request to a REST API endpoint and checks the effect of the submission in the database.

                                                                                                                                                            +

                                                                                                                                                            All of these actions fall squarely into what a developer would do, not into what a user could/should be able to do.

                                                                                                                                                            +

                                                                                                                                                            Furthermore, the format of the test is not the same as the one used in the acceptance test.

                                                                                                                                                            +

                                                                                                                                                            The acceptance test is written in the most eloquent testing format supported by Codeception, the Cept format, this test uses a more PHPUnit-like format, the Cest format.

                                                                                                                                                            +

                                                                                                                                                            While the first is easier to skim for non-developers the second harnesses the power of a re-using pieces of code, the page creation and navigation in the example, to optimize the test code.

                                                                                                                                                            +

                                                                                                                                                            Integration tests

                                                                                                                                                            +

                                                                                                                                                            In brief: test code modules in the context of a WordPress website.

                                                                                                                                                            +

                                                                                                                                                            In this type of test the WordPress, and additional plugins code, is loaded in the same variable scope as the tests; this is why in the example below I'm using classes (WP_REST_Request, WP_REST_Response) and methods (register_rest_route) defined by WordPress, not the plugin code.

                                                                                                                                                            +

                                                                                                                                                            The REST API request sent by the application form will be handled by a class, Acme\Signup\SubmissionHandler, that's been attached to the /wp-json/acme/v1/signup path:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// file src/rest.php
                                                                                                                                                            +
                                                                                                                                                            +add_action( 'rest_api_init', function () {
                                                                                                                                                            +    register_rest_route( 'acme/v1', '/signup', array(
                                                                                                                                                            +        'methods' => 'POST',
                                                                                                                                                            +        'callback' => function( WP_Rest_Request $request ) {
                                                                                                                                                            +            $email_validator = new Acme\Signup\EmailValidator();
                                                                                                                                                            +            $handler = new Acme\Signup\SubmissionHandler( $email_validator );
                                                                                                                                                            +
                                                                                                                                                            +            return $handler->handle( $request );
                                                                                                                                                            +        },
                                                                                                                                                            +    ) );
                                                                                                                                                            +} );
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            I want to test the chain of classes and methods that's handling such a request in the context of a WordPress installation.

                                                                                                                                                            +

                                                                                                                                                            Integration is usually about testing "modules" of code: groups of classes and functions working together to provide a service or complete a task.

                                                                                                                                                            +

                                                                                                                                                            In the context of integration testing the class dependencies and/or the context are not mocked.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// file tests/integration/SubmissionHandlingTest.php
                                                                                                                                                            +
                                                                                                                                                            +class SubmissionHandlingTest extends \Codeception\TestCase\WPTestCase {
                                                                                                                                                            +    public function test_good_request() {
                                                                                                                                                            +        $request = new WP_Rest_Request();
                                                                                                                                                            +        $request->set_body_params( [ 'name' => 'luca', 'email' => 'luca@theaveragedev.com' ] );
                                                                                                                                                            +        $handler = new  Acme\Signup\SubmissionHandler();
                                                                                                                                                            +
                                                                                                                                                            +        $response = $handler->handle( $request );
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertIntsanceOf( WP_REST_Response::class, $response );
                                                                                                                                                            +        $this->assertEquals( 200, $response->get_status() );
                                                                                                                                                            +        $this->assertInstanceOf( Acme\Signup\Submission_Good::class, $handler->last_submission() );
                                                                                                                                                            +        $this->assertEquals( 'luca', $handler->last_submission()->name() );
                                                                                                                                                            +        $this->assertEquals( 'luca@theaveragedev.com', $handler->last_submission()->email() );
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_bad_email_request() {
                                                                                                                                                            +        $request = new WP_Rest_Request();
                                                                                                                                                            +        $request->set_body_params( [ 'name' => 'luca', 'email' => 'not-a-valid-email' ] );
                                                                                                                                                            +        $handler = new  Acme\Signup\SubmissionHandler();
                                                                                                                                                            +
                                                                                                                                                            +        $response = $handler->handle( $request );
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertIntsanceOf( WP_REST_Response::class, $response );
                                                                                                                                                            +        $this->assertEquals( 400, $response->get_status() );
                                                                                                                                                            +        $this->assertInstanceOf( Acme\Signup\Submission_Bad::class, $handler->last_submission() );
                                                                                                                                                            +        $this->assertEquals( 'luca', $handler->last_submission()->name() );
                                                                                                                                                            +        $this->assertEquals( 'not-a-valid-email', $handler->last_submission()->email() );
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The test format used is the familiar PhpUnit one; the only difference is the base test class that's being extended (\Codeception\TestCase\WPTestCase) is one provided by wp-browser.

                                                                                                                                                            +

                                                                                                                                                            In the context of WordPress "integration" might also mean testing that filters used by the code have the expected effect.

                                                                                                                                                            +

                                                                                                                                                            Unit tests

                                                                                                                                                            +

                                                                                                                                                            In brief: test single classes or functions in isolation.

                                                                                                                                                            +

                                                                                                                                                            The email address is validated by the Acme\Signup\EmailValidator class.

                                                                                                                                                            +

                                                                                                                                                            In the test code below I want to make sure the validation works as intended.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// file tests/unit/EmailValidatorTest.php
                                                                                                                                                            +
                                                                                                                                                            +class EmailValidatorTest extends Codeception\Test\Test {
                                                                                                                                                            +    public function test_good_email_validation() {
                                                                                                                                                            +        $validator = new Acme\Signup\EmailValidator();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertTrue( $validator->validate( 'luca@theaveragedev.com' ) ); 
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_bad_email_validation(){
                                                                                                                                                            +        $validator = new Acme\Signup\EmailValidator();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertTrue( $validator->validate( 'not-an-email' ) );
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_tricky_email_validation() {
                                                                                                                                                            +        $validator = new Acme\Signup\EmailValidator();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertTrue( $validator->validate( 'luca+signup@theaveragedev.com' ) ); 
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_validation_with_service(){
                                                                                                                                                            +        // Stub the validation service.
                                                                                                                                                            +        $validation_service = $this->prophesize( Acme\Signup\ValidationService::class );
                                                                                                                                                            +        $validation_service->validate( 'luca@theaveragedev.com' )->willReturn( true );
                                                                                                                                                            +        $validation_service->validate( 'lucas@theaveragedev.com' )->willReturn( false );
                                                                                                                                                            +        // Build the validator and set it to use the mock validation service.
                                                                                                                                                            +        $validator = new Acme\Signup\EmailValidator();
                                                                                                                                                            +        $validator->use_service( $validation_service->reveal() );
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertTrue( $validator->validate( 'luca@theaveragedev.com' ) );
                                                                                                                                                            +        $this->assertFalse( $validator->validate( 'lucas@theaveragedev.com' ) );
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Unit tests is where stubbing/mocking/spying of dependencies is used to gain total control over the input and context the class is using.

                                                                                                                                                            +

                                                                                                                                                            In the last test method I'm doing exactly that testing the email validator with an external validation service.

                                                                                                                                                            +

                                                                                                                                                            In the example I'm using the Prophecy mock engine that comes with PHPUnit along with its own mocking/stubbing/spying solutions.

                                                                                                                                                            +

                                                                                                                                                            There are other mocking engines (e.g Mockery) that could be used.

                                                                                                                                                            +

                                                                                                                                                            WordPress "unit" tests

                                                                                                                                                            +

                                                                                                                                                            In brief: test single classes or functions that require WordPress code in as much isolation as possible.

                                                                                                                                                            +

                                                                                                                                                            This is what most people referring to "unit tests" in the context of WordPress is talking about.

                                                                                                                                                            +

                                                                                                                                                            The purpose of this kind of tests is to test one class of a WordPress application, or one function, that requires a WordPress-defined function or class with a unit testing approach.

                                                                                                                                                            +

                                                                                                                                                            In the example below I'm testing the Acme\Signup\SubmissionHandler class on a "unit" level making sure it will mark a request as bad if the email is not a valid one.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// file tests/unit/SubmissionHandlerTest.php
                                                                                                                                                            +class SubmissionHandlerTest extends Codeception\Test\Test {
                                                                                                                                                            +    protected  $request;
                                                                                                                                                            +    protected $validator;
                                                                                                                                                            +
                                                                                                                                                            +    public function setUp() {
                                                                                                                                                            +        // Mock the request.
                                                                                                                                                            +        $this->request = $this->prophesize( WP_REST_Request::class );
                                                                                                                                                            +        // Spy on the validator.
                                                                                                                                                            +        $this->validator = $this->prophesize( Acme\Signup\EmailValidator::class );
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_email_is_validated_by_default() {
                                                                                                                                                            +        $this->request->get_param( 'name' )->willReturn( 'luca' );
                                                                                                                                                            +        $this->request->get_param( 'email' )->willReturn( 'luca@theaveragedev.com' );
                                                                                                                                                            +
                                                                                                                                                            +        $handler = new Acme\Signup\SubmissionHandler( $this->validator->reveal() );
                                                                                                                                                            +        $handler->set_validator( $this->validator );
                                                                                                                                                            +        $response = $handler->handle( $this->request->reveal() );
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertInstanceOf( WP_REST_Response::class, $response );
                                                                                                                                                            +        // Verify on the validator spy.
                                                                                                                                                            +        $this->validator->validate( 'luca@theaveragedev.com' )->shouldHaveBeenCalled();
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_will_not_validate_email_if_missing() {
                                                                                                                                                            +        $this->request->get_param( 'name' )->willReturn( 'luca' );
                                                                                                                                                            +        $this->request->get_param( 'email' )->willReturn( '' );
                                                                                                                                                            +
                                                                                                                                                            +        $handler = new Acme\Signup\SubmissionHandler( $this->validator->reveal() );
                                                                                                                                                            +        $handler->set_validator( $this->validator );
                                                                                                                                                            +        $response = $handler->handle( $this->request->reveal() );
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertInstanceOf( WP_REST_Response::class, $response );
                                                                                                                                                            +        // Verify on the validator spy.
                                                                                                                                                            +        $this->validator->validate( Argument::any() )->shouldNotHaveBeenCalled();
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The class uses the WP_REST_Request and WP_Rest_Response classes as input and output and will probably, internally, use more functions defined by WordPress.

                                                                                                                                                            +

                                                                                                                                                            One solution to avoid loading WordPress, could be to rewrite test versions of each and all the WordPress functions and classes needed by all the classes I want to unit test; this would require updating each time the classes requirements change.

                                                                                                                                                            +

                                                                                                                                                            Furthermore internationalization (e.g. __()) and filtering (e.g apply_filters) functions would not need to be mocked if not in specific cases and would pretty much be copy and paste versions of the WordPres ones.

                                                                                                                                                            +

                                                                                                                                                            Loading single pieces of WordPress is a dangerous and brittle endeavour and it's not supported by the +framework.

                                                                                                                                                            +

                                                                                                                                                            To avoid all this WordPress "unit tests" pay the price of having to bootstrap WordPress, thus requiring a database connection.

                                                                                                                                                            +

                                                                                                                                                            This kind of test setup and level is the one you can see in the PHPUnit Core suite of WordPress itself.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/migration/from-version-2-to-version-3/index.html b/v3/migration/from-version-2-to-version-3/index.html new file mode 100644 index 000000000..5a4076b44 --- /dev/null +++ b/v3/migration/from-version-2-to-version-3/index.html @@ -0,0 +1,2974 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Version 2 to version 3 - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Version 2 to version 3

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Migrating projects from version 2 of wp-browser to version 3

                                                                                                                                                            +

                                                                                                                                                            Version 3 of wp-browser removed, to allow for broader compatibility with PHP and Composer versions, some of its +dependencies and modified some of its methods.
                                                                                                                                                            +Here is a list of changes and the suggested courses of action:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Removed symfony/process to launch and manage external processes; re-add it your project development +requirements using composer require --dev symfony/process.
                                                                                                                                                            • +
                                                                                                                                                            • Removed the wp-cli/wp-cli-bundle dependency; if you were relying on non-core + packages, then re-add it to your project development requirements using composer require --dev wp-cli/wp-cli-bundle.
                                                                                                                                                            • +
                                                                                                                                                            • Removed the WithWpCli::executeBackgroundWpCliCommand trait method, and, as a consequence, the +WPCLI::executeBackgroundWpCliCommand module method; you could have used the latter, if this was the case, then +require the symfony/process as explained above and launch processes in background using its API; find out more.
                                                                                                                                                            • +
                                                                                                                                                            • Refactored the WPCLI module to build and escape string command lines differently; the handling of command-line arguments +for the WPCLI module has been modified to make it a bit more consistent and robust; as a consequence, you might experience +some breakages in string commands that used to work correctly before; should this be the case then either modify +your code to provide the command in array format (taking care of the correct escaping in your code), or make sure to +pass a correctly structured command string to the WPCLI module.
                                                                                                                                                            • +
                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WPBrowser/index.html b/v3/modules/WPBrowser/index.html new file mode 100644 index 000000000..304514dce --- /dev/null +++ b/v3/modules/WPBrowser/index.html @@ -0,0 +1,3561 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPBrowser - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WPBrowser module

                                                                                                                                                            +

                                                                                                                                                            This module should be used in acceptance and functional tests, see levels of testing for more information.

                                                                                                                                                            +

                                                                                                                                                            This module extends the PHPBrowser module adding WordPress-specific configuration parameters and methods.

                                                                                                                                                            +

                                                                                                                                                            The module simulates a user interaction with the site without Javascript support; if you need to test your project with Javascript support use the WPWebDriver module.

                                                                                                                                                            +

                                                                                                                                                            Module requirements for Codeception 4.0+

                                                                                                                                                            +

                                                                                                                                                            This module requires the codeception/module-phpbrowser Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                            +

                                                                                                                                                            To install the package run:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev codeception/module-phpbrowser:^1.0
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +

                                                                                                                                                            Since this module extends the PHPBrowser module provided by Codeception, please refer to the PHPBrowser configuration section for more information about the base configuration parameters.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • url required - Start URL of your WordPress project, e.g. http://wp.test.
                                                                                                                                                            • +
                                                                                                                                                            • headers - Default headers are set before each test; this might be useful to simulate a specific user agent during the tests or to identify the request source. Note that the headers defined in the config should be prefaced with HTTP_ in your wp-config.php file. This can be used to select which database to use.
                                                                                                                                                            • +
                                                                                                                                                            • handler (default: curl) - The Guzzle handler to use. By default curl is used, also possible to pass stream, or any valid class name as Handler.
                                                                                                                                                            • +
                                                                                                                                                            • middleware - The Guzzle middlewares to add. An array of valid callables is required; see here for more information.
                                                                                                                                                            • +
                                                                                                                                                            • curl - curl options; only applied if using the curl handler; more options are available.
                                                                                                                                                            • +
                                                                                                                                                            • adminUsername required - This is the login name, not the "nice" name, of the administrator user of the WordPress test site. This will be used to fill the username field in WordPress login page.
                                                                                                                                                            • +
                                                                                                                                                            • adminPassword required - This is the the password of the administrator use of the WordPress test site. This will be used to fill the password in WordPress login page.
                                                                                                                                                            • +
                                                                                                                                                            • adminPath required - The path, relative to the WordPress test site home URL, to the administration area, usually /wp-admin.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example configuration

                                                                                                                                                            +
                                                                                                                                                              modules:
                                                                                                                                                            +      enabled:
                                                                                                                                                            +          - WPBrowser
                                                                                                                                                            +      config:
                                                                                                                                                            +          WPBrowser:
                                                                                                                                                            +              url: 'http://wordpress.localhost'
                                                                                                                                                            +              adminUsername: 'admin'
                                                                                                                                                            +              adminPassword: 'password'
                                                                                                                                                            +              adminPath: '/wp-admin'
                                                                                                                                                            +              headers:
                                                                                                                                                            +                X_TEST_REQUEST: 1
                                                                                                                                                            +                X_WPBROWSER_REQUEST: 1
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Read here how to use the headers information to automatically change the database during acceptance and functional tests.

                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • activatePlugin($pluginSlug) : void
                                                                                                                                                              + In the plugin administration screen activates a plugin clicking the "Activate" link.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication to the admin area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • activateTheme($slug) : void
                                                                                                                                                              + Activates a theme.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amEditingPostWithId($id) : void
                                                                                                                                                              + Go to the admin page to edit the post with the specified ID.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication the admin area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amEditingUserWithId($id) : void
                                                                                                                                                              + Go to the admin page to edit the user with the specified ID.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication the admin area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              amHttpAuthenticated($username, $password) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnAdminAjaxPage([$queryVars]) : void
                                                                                                                                                              + Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication, nonces or authorization.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amOnAdminPage($page) : void
                                                                                                                                                              + Go to a page in the admininstration area of the site.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            This method will not handle authentication to the administration area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              amOnCronPage([$queryVars]) : void
                                                                                                                                                              + Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnPage($page) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnPagesPage() : void
                                                                                                                                                              + Go the "Pages" administration screen.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amOnPluginsPage() : void
                                                                                                                                                              + Go to the plugins administration screen.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              amOnSubdomain($subdomain) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnThemesPage() : void
                                                                                                                                                              + Moves to the themes administration page.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnUrl($url) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              attachFile($field, $filename) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              checkOption($option) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              click($link, [$context]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              deactivatePlugin($pluginSlug) : void
                                                                                                                                                              + In the plugin administration screen deactivate a plugin clicking the "Deactivate" link.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugins administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • deleteHeader($name) : void
                                                                                                                                                              + Deletes the header with the passed name. Subsequent requests + will not have the deleted header in its request.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example: +

                                                                                                                                                            <?php
                                                                                                                                                            +$I->haveHttpHeader('X-Requested-With', 'Codeception');
                                                                                                                                                            +$I->amOnPage('test-headers.php');
                                                                                                                                                            +// ...
                                                                                                                                                            +$I->deleteHeader('X-Requested-With');
                                                                                                                                                            +$I->amOnPage('some-other-page.php');
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              dontSee($text, [$selector]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCheckboxIsChecked($checkbox) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCurrentUrlEquals($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCurrentUrlMatches($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeElement($selector, [$attributes]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInCurrentUrl($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInField($field, $value) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInFormFields($formSelector, array $params) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInSource($raw) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInTitle($title) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeLink($text, [$url]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeOptionIsSelected($selector, $optionText) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeePluginInstalled($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is not installed in the plugins administration screen.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • dontSeeResponseCodeIs($code) : void
                                                                                                                                                              + Checks that response code is equal to value provided.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->dontSeeResponseCodeIs(200);
                                                                                                                                                            +
                                                                                                                                                            +// recommended \Codeception\Util\HttpCode
                                                                                                                                                            +$I->dontSeeResponseCodeIs(\Codeception\Util\HttpCode::OK);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • executeInGuzzle(Closure $function) : void
                                                                                                                                                              + Low-level API method. + If Codeception commands are not enough, use Guzzle HTTP Client methods directly
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->executeInGuzzle(function (\GuzzleHttp\Client $client) {
                                                                                                                                                            +     $client->get('/get', ['query' => ['foo' => 'bar']]);
                                                                                                                                                            +});
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            It is not recommended to use this command on a regular basis. + If Codeception lacks important Guzzle Client methods, implement them and submit patches.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              fillField($field, $value) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              followRedirect() : void
                                                                                                                                                              + Follow pending redirect if there is one.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->followRedirect();
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • grabActiveTheme() : void
                                                                                                                                                              + Returns the slug of the currently active themes.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              grabAttributeFrom($cssOrXpath, $attribute) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabAvailableThemes([$classes]) : void
                                                                                                                                                              + Returns the list of available themes.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              grabCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabCookiesWithPattern($cookiePattern) : void
                                                                                                                                                              + Returns all the cookies whose name matches a regex pattern.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabFromCurrentUrl([$uri]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabMultiple($cssOrXpath, [$attribute]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabPageSource() : void
                                                                                                                                                              + Grabs current page source code.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabTextFrom($cssOrXPathOrRegex) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabValueFrom($field) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabWordPressTestCookie([$name]) : void
                                                                                                                                                              + Returns WordPress default test cookie object if present.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              haveHttpHeader($name, $value) : void
                                                                                                                                                              + Sets the HTTP header to the passed value - which is used on + subsequent HTTP requests through PhpBrowser.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example: +

                                                                                                                                                            <?php
                                                                                                                                                            +$I->haveHttpHeader('X-Requested-With', 'Codeception');
                                                                                                                                                            +$I->amOnPage('test-headers.php');
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            To use special chars in Header Key use HTML Character Entities: + Example: + Header with underscore - 'Client_Id' + should be represented as - 'Client_Id' or 'Client_Id'

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->haveHttpHeader('Client&#95;Id', 'Codeception');
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • haveServerParameter($name, $value) : void
                                                                                                                                                              + Sets SERVER parameter valid for all next requests.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            $I->haveServerParameter('name', 'value');
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              logOut([$redirectTo]) : void
                                                                                                                                                              + Navigate to the default WordPress logout page and click the logout link.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              loginAs($username, $password) : void
                                                                                                                                                              + Login as the specified user.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not follow redirection, after the login, to any page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • loginAsAdmin() : void
                                                                                                                                                              + Login as the administrator user using the credentials specified in the module configuration.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not follow redirection, after the login, to any page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              makeHtmlSnapshot([$name]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              moveBack([$numberOfSteps]) : void
                                                                                                                                                              + Moves back in history.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              resetCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              see($text, [$selector]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCheckboxIsChecked($checkbox) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCurrentUrlEquals($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCurrentUrlMatches($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeElement($selector, [$attributes]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeErrorMessage([$classes]) : void
                                                                                                                                                              + In an administration screen look for an error admin notice.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The check is class-based to decouple from internationalization. + The method will not handle authentication and navigation the administration area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              seeInCurrentUrl($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInField($field, $value) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInFormFields($formSelector, array $params) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInSource($raw) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInTitle($title) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeLink($text, [$url]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeMessage([$classes]) : void
                                                                                                                                                              + In an administration screen look for an admin notice.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The check is class-based to decouple from internationalization. + The method will not handle authentication and navigation the administration area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              seeNumberOfElements($selector, $expected) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeOptionIsSelected($selector, $optionText) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seePageNotFound() : void
                                                                                                                                                              + Asserts that current page has 404 response status code.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seePluginActivated($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is activated in the plugin administration screen.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seePluginDeactivated($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is not activated in the plugins administration screen.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seePluginInstalled($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is installed, no matter its activation status, in the plugin administration screen.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seeResponseCodeIs($code) : void
                                                                                                                                                              + Checks that response code is equal to value provided.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->seeResponseCodeIs(200);
                                                                                                                                                            +
                                                                                                                                                            +// recommended \Codeception\Util\HttpCode
                                                                                                                                                            +$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              seeResponseCodeIsBetween($from, $to) : void
                                                                                                                                                              + Checks that response code is between a certain range. Between actually means [from <= CODE <= to]

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeResponseCodeIsClientError() : void
                                                                                                                                                              + Checks that the response code is 4xx

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeResponseCodeIsRedirection() : void
                                                                                                                                                              + Checks that the response code 3xx

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeResponseCodeIsServerError() : void
                                                                                                                                                              + Checks that the response code is 5xx

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeResponseCodeIsSuccessful() : void
                                                                                                                                                              + Checks that the response code 2xx

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeThemeActivated($slug) : void
                                                                                                                                                              + Verifies that a theme is active.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seeWpDiePage() : void
                                                                                                                                                              + Checks that the current page is one generated by the wp_die function.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will try to identify the page based on the default WordPress die page HTML attributes.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              selectOption($select, $option) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              sendAjaxGetRequest($uri, [$params]) : void
                                                                                                                                                              + Sends an ajax GET request with the passed parameters. + See sendAjaxPostRequest()

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              sendAjaxPostRequest($uri, [$params]) : void
                                                                                                                                                              + Sends an ajax POST request with the passed parameters. + The appropriate HTTP header is added automatically: + X-Requested-With: XMLHttpRequest + Example: +

                                                                                                                                                              <?php
                                                                                                                                                              +$I->sendAjaxPostRequest('/add-task', ['task' => 'lorem ipsum']);
                                                                                                                                                              +
                                                                                                                                                              + Some frameworks (e.g. Symfony) create field names in the form of an "array": + <input type="text" name="form[task]"> + In this case you need to pass the fields like this: +
                                                                                                                                                              <?php
                                                                                                                                                              +$I->sendAjaxPostRequest('/add-task', ['form' => [
                                                                                                                                                              +    'task' => 'lorem ipsum',
                                                                                                                                                              +    'category' => 'miscellaneous',
                                                                                                                                                              +]]);
                                                                                                                                                              +

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              sendAjaxRequest($method, $uri, [$params]) : void
                                                                                                                                                              + Sends an ajax request, using the passed HTTP method. + See sendAjaxPostRequest() + Example: +

                                                                                                                                                              <?php
                                                                                                                                                              +$I->sendAjaxRequest('PUT', '/posts/7', ['title' => 'new title']);
                                                                                                                                                              +

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              setCookie($name, $val, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              setHeader($name, $value) : void
                                                                                                                                                              + Alias to haveHttpHeader

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              setMaxRedirects($maxRedirects) : void
                                                                                                                                                              + Sets the maximum number of redirects that the Client can follow.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->setMaxRedirects(2);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • setServerParameters(array $params) : void
                                                                                                                                                              + Sets SERVER parameters valid for all next requests. + this will remove old ones.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            $I->setServerParameters([]);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • startFollowingRedirects() : void
                                                                                                                                                              + Enables automatic redirects to be followed by the client.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->startFollowingRedirects();
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • stopFollowingRedirects() : void
                                                                                                                                                              + Prevents automatic redirects to be followed by the client.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->stopFollowingRedirects();
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              submitForm($selector, array $params, [$button]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              switchToIframe($name) : void
                                                                                                                                                              + Switch to iframe or frame on the page.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example: +

                                                                                                                                                            <iframe name="another_frame" src="http://example.com">
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +# switch to iframe
                                                                                                                                                            +$I->switchToIframe("another_frame");
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • uncheckOption($option) : void
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            This class extends \Codeception\Module\PhpBrowser

                                                                                                                                                            +

                                                                                                                                                            This class implements \Codeception\Lib\Interfaces\MultiSession, \Codeception\Lib\Interfaces\Remote, \Codeception\Lib\Interfaces\Web, \Codeception\Lib\Interfaces\PageSourceSaver, \Codeception\Lib\Interfaces\ElementLocator, \Codeception\Lib\Interfaces\ConflictsWithModule

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WPCLI/index.html b/v3/modules/WPCLI/index.html new file mode 100644 index 000000000..e68f2e704 --- /dev/null +++ b/v3/modules/WPCLI/index.html @@ -0,0 +1,3361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPCLI - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WPCLI module

                                                                                                                                                            +

                                                                                                                                                            This module should be used in acceptance and functional tests to setup, or verify, tests pre and post conditions using WP-CLI commands.
                                                                                                                                                            +This module allows invoking WP-CLI commands, refer to the official site for more information.

                                                                                                                                                            +

                                                                                                                                                            The module will use its own version of WP-CLI, not the one installed in the machine running the tests!

                                                                                                                                                            +

                                                                                                                                                            By default, wp-browser will only include the wp-cli/wp-cli package; this package contains the basic files to run WP-CLI and does not contain all the commands that come with a typical wp-cli installation.
                                                                                                                                                            +If, in your tests, you require all the commands that usually come installed with WP-CLI, then you should require the wp-cli/wp-cli-bundle package as a development dependency of your project, see below.

                                                                                                                                                            +

                                                                                                                                                            Fixing "not a registered command" issue

                                                                                                                                                            +

                                                                                                                                                            To keep the conflicts at a manageable level, the wp-browser project does not include all the commands WP-CLI usually comes bundled with.
                                                                                                                                                            +Running, in the context of an automated test, a WP-CLI command that would work on your machine, e.g. wp plugin list --status=active, will not work on a default installation of wp-browser and you will get the following error message:

                                                                                                                                                            +
                                                                                                                                                            [ModuleException] WPCLI: wp-cli terminated with status [1] and output [Error: 'plugin' is not a registered wp command. See 'wp help' for available commands.]
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            To resolve the message just add the package you require as a development dependency or add the whole WP-CLI bundle:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev wp-cli/wp-cli-bundle
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The package will make all the default WP-CLI commands available to the WP-CLI version used in tests.

                                                                                                                                                            +

                                                                                                                                                            Module requirements for Codeception 4.0+

                                                                                                                                                            +

                                                                                                                                                            This module requires the codeception/module-cli Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                            +

                                                                                                                                                            To install the package run:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev codeception/module-cli:^1.0
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Detecting requests coming from this module

                                                                                                                                                            +

                                                                                                                                                            When it runs this module will set the WPBROWSER_HOST_REQUEST environment variable.
                                                                                                                                                            +You can detect and use that information to, as an example, use the correct database in your test site wp-config.php file: +

                                                                                                                                                            <?php
                                                                                                                                                            +if ( 
                                                                                                                                                            +    // Custom header.
                                                                                                                                                            +    isset( $_SERVER['HTTP_X_TESTING'] )
                                                                                                                                                            +    // Custom user agent.
                                                                                                                                                            +    || ( isset( $_SERVER['HTTP_USER_AGENT'] ) && $_SERVER['HTTP_USER_AGENT'] === 'wp-browser' )
                                                                                                                                                            +    // The env var set by the WPClIr or WordPress modules.
                                                                                                                                                            +    || getenv( 'WPBROWSER_HOST_REQUEST' )
                                                                                                                                                            +) {
                                                                                                                                                            +    // Use the test database if the request comes from a test.
                                                                                                                                                            +    define( 'DB_NAME', 'wordpress_test' );
                                                                                                                                                            +} else {
                                                                                                                                                            +    // Else use the default one.
                                                                                                                                                            +    define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            +}
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • path required - the absolute, or relative, path to the WordPress root folder. This will be mapped to the --path argument of the wp-cli binary.
                                                                                                                                                            • +
                                                                                                                                                            • throw - defaults to true to throw an exception when a wp-cli command does not return an exit status of 0; if set to false then the exit status of the commands will be returned as is.
                                                                                                                                                            • +
                                                                                                                                                            • timeout - defaults to 60 (seconds) to set each process execution timeout to a certain value; set to null, false or 0 to disable timeout completely.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Additionally the module configuration will forward any configuration parameter to wp-cli as a flag or option. +In the example configuration below the allow-root flag and the some-option option will be passed to wp-cli directly and prepended to the command as global options.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Note: these extract configuration flags and options will be prepended to all commands executed by wp-cli!

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Environment configuration

                                                                                                                                                            +

                                                                                                                                                            The wp-cli binary supports a set of environment variables to modify its behavior.

                                                                                                                                                            +

                                                                                                                                                            These environment variables can be set on the commands ran by the WPCLI module using the optional env array in the module configuration.
                                                                                                                                                            +The example configuration below shows all of them with some example values.
                                                                                                                                                            +Most of the times you won't need any of these, but they are there for more fine-grained control over the module operations.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The module is not validating the environment variables in any way! Those values will be evaluated by wp-cli at runtime and might generate errors if not correctly configured.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Example configuration

                                                                                                                                                            +
                                                                                                                                                            modules:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - WPCLI
                                                                                                                                                            +    config:
                                                                                                                                                            +        WPCLI:
                                                                                                                                                            +            path: /Users/Luca/Sites/wp
                                                                                                                                                            +            throw: true
                                                                                                                                                            +            timeout: 60
                                                                                                                                                            +            # This will be prepended to the command, `wp --allow-root <command>`.
                                                                                                                                                            +            allow-root: true
                                                                                                                                                            +            # This will be prepended to the command, `wp --some-option=some-value <command>`.
                                                                                                                                                            +            some-option: some-value
                                                                                                                                                            +            env:
                                                                                                                                                            +                # Any one of these, if provided, will be set as environment variable for the the cli command process. 
                                                                                                                                                            +                # See https://make.wordpress.org/cli/handbook/config/#environment-variables for information.
                                                                                                                                                            +                # Equivalent to `WP_CLI_STRICT_ARGS_MODE=1 wp <command>'.
                                                                                                                                                            +                strict-args: true
                                                                                                                                                            +                # Equivalent to `WP_CLI_CACHE_DIR=/tmp/wp-cli-cache wp <command>'.
                                                                                                                                                            +                cache-dir: '/tmp/wp-cli-cache'
                                                                                                                                                            +                # Equivalent to `WP_CLI_CONFIG_PATH=/app/public wp <command>'.
                                                                                                                                                            +                config-path: '/app/public'
                                                                                                                                                            +                # Equivalent to `WP_CLI_CUSTOM_SHELL=/bin/zsh wp <command>'.
                                                                                                                                                            +                custom-shell: '/bin/zsh'
                                                                                                                                                            +                # Equivalent to `WP_CLI_DISABLE_AUTO_CHECK_UPDATE=1 wp <command>'.
                                                                                                                                                            +                disable-auto-update: true
                                                                                                                                                            +                # Equivalent to `WP_CLI_PACKAGES_DIR=/wp-cli/packages wp <command>'.
                                                                                                                                                            +                packages-dir: '/wp-cli/packages'
                                                                                                                                                            +                # Equivalent to `WP_CLI_PHP=/usr/local/bin/php/7.2/php wp <command>'.
                                                                                                                                                            +                php: '/usr/local/bin/php/7.2/php'
                                                                                                                                                            +                # Equivalent to `WP_CLI_PHP_ARGS='foo=bar some=23' wp <command>'.
                                                                                                                                                            +                php-args: 'foo=bar some=23'
                                                                                                                                                            +
                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            + + +

                                                                                                                                                            buildFullCommand

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Builds the full command to run including the PHP binary and the wp-cli boot file path.

                                                                                                                                                            +
                                                                                                                                                            // This method is defined in the WithWpCli trait.
                                                                                                                                                            +  // Set the wp-cli path, `$this` is a test case.
                                                                                                                                                            +  $this->setUpWpCli( '/var/www/html' );
                                                                                                                                                            +  // Builds the full wp-cli command, including the `path` variable.
                                                                                                                                                            +  $fullCommand =  $this->buildFullCommand(['core', 'version']);
                                                                                                                                                            +  // The full command can then be used to run it with another process handler.
                                                                                                                                                            +  $wpCliProcess = new Process($fullCommand);
                                                                                                                                                            +  $wpCliProcess->run();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/string $command - The command to run.
                                                                                                                                                            + +

                                                                                                                                                            cli

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Executes a wp-cli command targeting the test WordPress installation. minus wp. For back-compatibility purposes you can still pass the commandline as a string, but the array format is the preferred and supported method.

                                                                                                                                                            +
                                                                                                                                                            // Activate a plugin via wp-cli in the test WordPress site.
                                                                                                                                                            +  $I->cli(['plugin', 'activate', 'my-plugin']);
                                                                                                                                                            +  // Change a user password.
                                                                                                                                                            +  $I->cli(['user', 'update', 'luca', '--user_pass=newpassword']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/string/\Codeception\Module\array $userCommand - The string of command and parameters as it would be passed to wp-cli
                                                                                                                                                            + +

                                                                                                                                                            cliToArray

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the output of a wp-cli command as an array optionally allowing a callback to process the output. minus wp. For back-compatibility purposes you can still pass the commandline as a string, but the array format is the preferred and supported method.

                                                                                                                                                            +
                                                                                                                                                            // Return a list of inactive themes, like ['twentyfourteen', 'twentyfifteen'].
                                                                                                                                                            +  $inactiveThemes = $I->cliToArray(['theme', 'list', '--status=inactive', '--field=name']);
                                                                                                                                                            +  // Get the list of installed plugins and only keep the ones starting with "foo".
                                                                                                                                                            +  $fooPlugins = $I->cliToArray(['plugin', 'list', '--field=name'], function($output){
                                                                                                                                                            +  return array_filter(explode(PHP_EOL, $output), function($name){
                                                                                                                                                            +  return strpos(trim($name), 'foo') === 0;
                                                                                                                                                            +  });
                                                                                                                                                            +  });
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/string/\Codeception\Module\array $userCommand - The string of command and parameters as it would be passed to wp-cli
                                                                                                                                                            • +
                                                                                                                                                            • \callable $splitCallback - An optional callback function to split the results array.
                                                                                                                                                            + +

                                                                                                                                                            cliToString

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the output of a wp-cli command as a string. minus wp. For back-compatibility purposes you can still pass the commandline as a string, but the array format is the preferred and supported method.

                                                                                                                                                            +
                                                                                                                                                            // Return the current site administrator email, using string command format.
                                                                                                                                                            +  $adminEmail = $I->cliToString('option get admin_email');
                                                                                                                                                            +  // Get the list of active plugins in JSON format, two ways.
                                                                                                                                                            +  $activePlugins = $I->cliToString(['plugin', 'list','--status=active', '--format=json']);
                                                                                                                                                            +  $activePlugins = $I->cliToString(['option', 'get', 'active_plugins' ,'--format=json']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/\Codeception\Module\array $userCommand - The string of command and parameters as it would be passed to wp-cli
                                                                                                                                                            + +

                                                                                                                                                            dontSeeInShellOutput

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that output from last command doesn't contain text.

                                                                                                                                                            +
                                                                                                                                                            // Return the current site administrator email, using string command format.
                                                                                                                                                            +  $I->cli('plugin list --status=active');
                                                                                                                                                            +  $I->dontSeeInShellOutput('my-inactive/plugin.php');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $text - The text to assert is not in the output.
                                                                                                                                                            + +

                                                                                                                                                            seeInShellOutput

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that output from last command contains text.

                                                                                                                                                            +
                                                                                                                                                            // Return the current site administrator email, using string command format.
                                                                                                                                                            +  $I->cli('option get admin_email');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $text - The text to assert is in the output.
                                                                                                                                                            + +

                                                                                                                                                            seeResultCodeIs

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks the result code from the last command.

                                                                                                                                                            +
                                                                                                                                                            // Return the current site administrator email, using string command format.
                                                                                                                                                            +  $I->cli('option get admin_email');
                                                                                                                                                            +  $I->seeResultCodeIs(0);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $code - The desired result code.
                                                                                                                                                            + +

                                                                                                                                                            seeResultCodeIsNot

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks the result code from the last command.

                                                                                                                                                            +
                                                                                                                                                            // Return the current site administrator email, using string command format.
                                                                                                                                                            +  $I->cli('invalid command');
                                                                                                                                                            +  $I->seeResultCodeIsNot(0);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $code - The result code the command should not have exited with.
                                                                                                                                                            + +

                                                                                                                                                            seeShellOutputMatches

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that output from the last command matches a given regular expression.

                                                                                                                                                            +
                                                                                                                                                            // Return the current site administrator email, using string command format.
                                                                                                                                                            +  $I->cli('option get admin_email');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $regex - The regex pattern, including delimiters, to assert the output matches against.
                                                                                                                                                            + +

                                                                                                                                                            This class extends \Codeception\Module

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WPDb/index.html b/v3/modules/WPDb/index.html new file mode 100644 index 000000000..937f3b389 --- /dev/null +++ b/v3/modules/WPDb/index.html @@ -0,0 +1,5528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPDb - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WPDb module

                                                                                                                                                            +

                                                                                                                                                            This module should be used in acceptance and functional tests, see levels of testing for more information.
                                                                                                                                                            +This module extends the Db module adding WordPress-specific configuration parameters and methods.
                                                                                                                                                            +The module provides methods to read, write and update the WordPress database directly, without relying on WordPress methods, using WordPress functions or triggering WordPress filters.

                                                                                                                                                            +

                                                                                                                                                            Module requirements for Codeception 4.0+

                                                                                                                                                            +

                                                                                                                                                            This module requires the codeception/module-db Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                            +

                                                                                                                                                            To install the package run:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev codeception/module-db:^1.0
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Backup your content

                                                                                                                                                            +

                                                                                                                                                            This module, like the Codeception Db one it extends, by default will load a database dump in the database it's using.
                                                                                                                                                            +This means that the database contents will be replaced by the dump contents on each run of a suite using the module.
                                                                                                                                                            +You can set the populate and cleanup parameters to false to prevent this default behavior but it's usually not what you need in an automated test.
                                                                                                                                                            +Make a backup of any database you're using in tests that contains any information you care about before you run any test!

                                                                                                                                                            +

                                                                                                                                                            Change the database used depending on whether you're running tests or not

                                                                                                                                                            +

                                                                                                                                                            The chore of having to plug different databases, or backup them, depending on whether you're manually testing the site or automatically testing can be mitigated switching them automatically depending on the browser user agent or request headers.
                                                                                                                                                            +This module was born to be used in acceptance and functional tests (see levels of testing for more information) and will often be coupled with modules like the WPBrowser one or the WPWebDriver one.
                                                                                                                                                            +Depending on which of the two modules is being used in the suite there are different ways to automate the "database switching".

                                                                                                                                                            +

                                                                                                                                                            Automatically changing database based on the browser user agent

                                                                                                                                                            +

                                                                                                                                                            If you would like to automate the "switching above" below you will find an example setup.
                                                                                                                                                            +Update the test site wp-config.php file from this: +

                                                                                                                                                            define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            +
                                                                                                                                                            + to this: +
                                                                                                                                                            <?php
                                                                                                                                                            +if ( 
                                                                                                                                                            +    // Custom header.
                                                                                                                                                            +    isset( $_SERVER['HTTP_X_TESTING'] )
                                                                                                                                                            +    // Custom user agent.
                                                                                                                                                            +    || ( isset( $_SERVER['HTTP_USER_AGENT'] ) && $_SERVER['HTTP_USER_AGENT'] === 'wp-browser' )
                                                                                                                                                            +    // The env var set by the WPClIr or WordPress modules.
                                                                                                                                                            +    || getenv( 'WPBROWSER_HOST_REQUEST' )
                                                                                                                                                            +) {
                                                                                                                                                            +    // Use the test database if the request comes from a test.
                                                                                                                                                            +    define( 'DB_NAME', 'wordpress_test' );
                                                                                                                                                            +} else {
                                                                                                                                                            +    // Else use the default one.
                                                                                                                                                            +    define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            +}
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            If you're using the WPWebDriver module set the user agent in the browser, in this example I'm setting the user agent in Chromedriver: +

                                                                                                                                                            class_name: AcceptanceTester
                                                                                                                                                            +modules:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - \Helper\Acceptance
                                                                                                                                                            +        - WPDb
                                                                                                                                                            +        - WPWebDriver
                                                                                                                                                            +    config:
                                                                                                                                                            +        WPDb:
                                                                                                                                                            +            dsn: 'mysql:host=%WP_DB_HOST%;dbname=%WP_DB_NAME%'
                                                                                                                                                            +            user: %WP_DB_USER%
                                                                                                                                                            +            password: %WP_DB_PASSWORD%
                                                                                                                                                            +            dump: tests/_data/dump.sql
                                                                                                                                                            +            populate: true
                                                                                                                                                            +            cleanup: false
                                                                                                                                                            +            url: '%WP_URL%'
                                                                                                                                                            +            tablePrefix: %WP_TABLE_PREFIX%
                                                                                                                                                            +            urlReplacement: true
                                                                                                                                                            +        WPWebDriver:
                                                                                                                                                            +            url: '%WP_URL%'
                                                                                                                                                            +            adminUsername: '%WP_ADMIN_USERNAME%'
                                                                                                                                                            +            adminPassword: '%WP_ADMIN_PASSWORD%'
                                                                                                                                                            +            adminPath: '%WP_ADMIN_PATH%'
                                                                                                                                                            +            browser: chrome
                                                                                                                                                            +            host: localhost
                                                                                                                                                            +            port: 4444
                                                                                                                                                            +            window_size: false
                                                                                                                                                            +            wait: 5
                                                                                                                                                            +            capabilities:
                                                                                                                                                            +              "goog:chromeOptions":
                                                                                                                                                            +                args:
                                                                                                                                                            +                  - "--headless"
                                                                                                                                                            +                  - "--disable-gpu"
                                                                                                                                                            +                  - "--disable-dev-shm-usage"
                                                                                                                                                            +                  - "--proxy-server='direct://'"
                                                                                                                                                            +                  - "--proxy-bypass-list=*"
                                                                                                                                                            +                  - "--no-sandbox"
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            If you're using the WPBrowser module send a specific header in the context of test requests: +

                                                                                                                                                            class_name: AcceptanceTester
                                                                                                                                                            +modules:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - \Helper\Acceptance
                                                                                                                                                            +        - WPDb
                                                                                                                                                            +        - WPBrowser
                                                                                                                                                            +    config:
                                                                                                                                                            +        WPDb:
                                                                                                                                                            +              dsn: 'mysql:host=%DB_HOST%;dbname=%WP_DB_NAME%'
                                                                                                                                                            +              user: %WP_DB_USER%
                                                                                                                                                            +              password: %WP_DB_PASSWORD%
                                                                                                                                                            +              dump: 'tests/_data/dump.sql'
                                                                                                                                                            +              populate: true
                                                                                                                                                            +              cleanup: true
                                                                                                                                                            +              reconnect: false
                                                                                                                                                            +              url: '%WP_URL%'
                                                                                                                                                            +              tablePrefix: 'wp_'
                                                                                                                                                            +        WPBrowser:
                                                                                                                                                            +              url: '%WP_URL%'
                                                                                                                                                            +              adminUsername: 'admin'
                                                                                                                                                            +              adminPassword: 'admin'
                                                                                                                                                            +              adminPath: '/wp-admin'
                                                                                                                                                            +              headers: 
                                                                                                                                                            +                X-Testing: 'wp-browser'
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • dsn required - the database POD DSN connection details; read more on PHP PDO documentation. If the database is accessible (as is the case on the latest version of [Local by Flywheel][http://localwp.com]) via unix socket, then the string to insert here should look like this mysql:unix_socket=/path/to/the/mysql.sock;dbname=wordpress.
                                                                                                                                                            • +
                                                                                                                                                            • user required - the database user.
                                                                                                                                                            • +
                                                                                                                                                            • password required - the database password.
                                                                                                                                                            • +
                                                                                                                                                            • url required - the full URL, including the HTTP scheme, of the website whose database is being accessed. WordPress uses hard-codece URLs in the database, that URL will be set by this module when applying the SQL dump file during population or cleanup.
                                                                                                                                                            • +
                                                                                                                                                            • dump required - defaults to null; sets the path, relative to the project root folder, or absolute to the SQL dump file that will be used to set the tests initial database fixture. If set to null then the populate, cleanup and populator parameters will be ignored.
                                                                                                                                                            • +
                                                                                                                                                            • populate - defaults to true to empty the target database and import the SQL dump(s) specified in the dump argument before the test suite is started.
                                                                                                                                                            • +
                                                                                                                                                            • cleanup - defaults to true empty the target database and import the SQL dump(s) specified in the dump argument before each test.
                                                                                                                                                            • +
                                                                                                                                                            • urlReplacement - defaults to true to replace, while using the built-in, PHP-based, dump import solution the hard-coded WordPress URL in the database with the specified one.
                                                                                                                                                            • +
                                                                                                                                                            • originalUrl - specifies the original URL hard-coded into the version controlled SQL dump files. This can help prevent some URL replacement issues when the urlReplacement configuration parameter is set to true.
                                                                                                                                                            • +
                                                                                                                                                            • populator - defaults to null, if set to an executable shell command then that command will be used to populate the database in place of the built-in PHP solution; URL replacement will not apply in this case. Read more about this on Codeception documentation.
                                                                                                                                                            • +
                                                                                                                                                            • reconnect - defaults to true to force the module to reconnect to the database before each test in place of only connecting at the start of the tests.
                                                                                                                                                            • +
                                                                                                                                                            • waitlock - defaults to 10; wait lock (in seconds) that the database session should use for DDL statements.
                                                                                                                                                            • +
                                                                                                                                                            • tablePrefix - defaults to wp_; sets the prefix of the tables that the module will manipulate.
                                                                                                                                                            • +
                                                                                                                                                            • letAdminEmailVerification - defaults to an empty value to remove the Administrator Email Verification screen introduced in WordPress 5.3. Set to true to not remove the screen and show it when an administrator user first logs in.
                                                                                                                                                            • +
                                                                                                                                                            • letCron - defaults to an empty value to avoid wp-cron from being spawned during tests. Setting this to true will let wp-cron requests to fire during tests.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example configuration

                                                                                                                                                            +
                                                                                                                                                            modules:
                                                                                                                                                            +  enabled:
                                                                                                                                                            +      - WPDb
                                                                                                                                                            +  config:
                                                                                                                                                            +      WPDb:
                                                                                                                                                            +          dsn: 'mysql:host=localhost;dbname=wordpress'
                                                                                                                                                            +          user: 'root'
                                                                                                                                                            +          password: 'password'
                                                                                                                                                            +          dump: 'tests/_data/dump.sql'
                                                                                                                                                            +          populate: true
                                                                                                                                                            +          cleanup: true
                                                                                                                                                            +          waitlock: 10
                                                                                                                                                            +          url: 'http://wordpress.localhost'
                                                                                                                                                            +          urlReplacement: true
                                                                                                                                                            +          tablePrefix: 'wp_'
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Using the module with the WPLoader one

                                                                                                                                                            +

                                                                                                                                                            This module is often used in conjunction with the WPLoader one to use WordPress-defined functions, classes and methods in acceptance or functional tests.
                                                                                                                                                            +The WPLoader module should be set to only load WordPress and this module should be listed, in the modules.enabled section of the suite configuration file before the WPLoader one:

                                                                                                                                                            +

                                                                                                                                                            modules:
                                                                                                                                                            +  enabled:
                                                                                                                                                            +      - WPDb # this before...
                                                                                                                                                            +      - WPLoader # ...this one.
                                                                                                                                                            +  config:
                                                                                                                                                            +      WPDb:
                                                                                                                                                            +        # ...
                                                                                                                                                            +      WPLoader:
                                                                                                                                                            +        loadOnly: true
                                                                                                                                                            +        # ... 
                                                                                                                                                            +
                                                                                                                                                            +This will avoid issues where the WPLoader module could exit, terminating the test run, due to an inconsistent database state.

                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            + + +

                                                                                                                                                            countRowsInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the number of table rows matching a criteria.

                                                                                                                                                            +
                                                                                                                                                            $I->haveManyPostsInDatabase(3, ['post_status' => 'draft' ]);
                                                                                                                                                            +  $I->haveManyPostsInDatabase(3, ['post_status' => 'private' ]);
                                                                                                                                                            +  // Make sure there are now the expected number of draft posts.
                                                                                                                                                            +  $postsTable = $I->grabPostsTableName();
                                                                                                                                                            +  $draftsCount = $I->countRowsInDatabase($postsTable, ['post_status' => 'draft']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $table - The table to count the rows in.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $criteria - Search criteria, if empty all table rows will be counted.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveAttachmentFilesInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes all the files attached with an attachment post, it will not remove the database entries. Requires the WPFilesystem module to be loaded in the suite.

                                                                                                                                                            +
                                                                                                                                                            $posts = $I->grabPostsTableName();
                                                                                                                                                            +  $attachmentIds = $I->grabColumnFromDatabase($posts, 'ID', ['post_type' => 'attachment']);
                                                                                                                                                            +  // This will only remove the files, not the database entries.
                                                                                                                                                            +  $I->dontHaveAttachmentFilesInDatabase($attachmentIds);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/int $attachmentIds - An attachment post ID or an array of attachment post IDs.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveAttachmentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an attachment from the posts table. table. the suite.

                                                                                                                                                            +
                                                                                                                                                            $postmeta = $I->grabpostmetatablename();
                                                                                                                                                            +  $thumbnailId = $I->grabFromDatabase($postmeta, 'meta_value', [
                                                                                                                                                            +  'post_id' => $id,
                                                                                                                                                            +  'meta_key'=>'thumbnail_id'
                                                                                                                                                            +  ]);
                                                                                                                                                            +  // Remove only the database entry (including postmeta) but not the files.
                                                                                                                                                            +  $I->dontHaveAttachmentInDatabase($thumbnailId);
                                                                                                                                                            +  // Remove the database entry (including postmeta) and the files.
                                                                                                                                                            +  $I->dontHaveAttachmentInDatabase($thumbnailId, true, true);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria to find the attachment post in the posts
                                                                                                                                                            • +
                                                                                                                                                            • bool $purgeMeta - If set to true then the meta for the attachment will be purged too.
                                                                                                                                                            • +
                                                                                                                                                            • bool $removeFiles - Remove all files too, requires the WPFilesystem module to be loaded in
                                                                                                                                                            + +

                                                                                                                                                            dontHaveBlogInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes one ore more blogs from the database.

                                                                                                                                                            +
                                                                                                                                                            // Remove the blog, all its tables and files.
                                                                                                                                                            +  $I->dontHaveBlogInDatabase(['path' => 'test/one']);
                                                                                                                                                            +  // Remove the blog entry, not the tables though.
                                                                                                                                                            +  $I->dontHaveBlogInDatabase(['blog_id' => $blogId]);
                                                                                                                                                            +  // Remove multiple blogs.
                                                                                                                                                            +  $I->dontHaveBlogInDatabase(['domain' => 'test']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria to find the blog rows in the blogs table.
                                                                                                                                                            • +
                                                                                                                                                            • bool $removeTables - Remove the blog tables.
                                                                                                                                                            • +
                                                                                                                                                            • bool $removeUploads - Remove the blog uploads; requires the WPFilesystem module.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveCommentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an entry from the comments table.

                                                                                                                                                            +
                                                                                                                                                            $I->dontHaveCommentInDatabase(['comment_post_ID' => 23, 'comment_url' => 'http://example.copm']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            • +
                                                                                                                                                            • bool $purgeMeta - If set to true then the meta for the comment will be purged too.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveCommentMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a post comment meta from the database

                                                                                                                                                            +
                                                                                                                                                            // Remove all meta for the comment with an ID of 23.
                                                                                                                                                            +  $I->dontHaveCommentMetaInDatabase(['comment_id' => 23]);
                                                                                                                                                            +  // Remove the `count` comment meta for the comment with an ID of 23.
                                                                                                                                                            +  $I->dontHaveCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'count']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Deletes a database entry. criteria.

                                                                                                                                                            +
                                                                                                                                                            $I->dontHaveInDatabase('custom_table', ['book_ID' => 23, 'book_genre' => 'fiction']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $table - The table name.
                                                                                                                                                            • +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An associative array of the column names and values to use as deletion
                                                                                                                                                            + +

                                                                                                                                                            dontHaveLinkInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a link from the database.

                                                                                                                                                            +
                                                                                                                                                            $I->dontHaveLinkInDatabase(['link_url' => 'http://example.com']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an entry from the options table.

                                                                                                                                                            +
                                                                                                                                                            // Remove the `foo` option.
                                                                                                                                                            +  $I->dontHaveOptionInDatabase('foo');
                                                                                                                                                            +  // Remove the 'bar' option only if it has the `baz` value.
                                                                                                                                                            +  $I->dontHaveOptionInDatabase('bar', 'baz');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The option name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed/null $value - If set the option will only be removed if its value matches the passed one.
                                                                                                                                                            + +

                                                                                                                                                            dontHavePostInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an entry from the posts table.

                                                                                                                                                            +
                                                                                                                                                            $posts = $I->haveManyPostsInDatabase(3, ['post_title' => 'Test {{n}}']);
                                                                                                                                                            +  $I->dontHavePostInDatabase(['post_title' => 'Test 2']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            • +
                                                                                                                                                            • bool $purgeMeta - If set to true then the meta for the post will be purged too.
                                                                                                                                                            + +

                                                                                                                                                            dontHavePostMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an entry from the postmeta table.

                                                                                                                                                            +
                                                                                                                                                            $postId = $I->havePostInDatabase(['meta_input' => ['rating' => 23]]);
                                                                                                                                                            +  $I->dontHavePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'rating']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontHavePostThumbnailInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Remove the thumbnail (featured image) from a post, if any. Please note: the method will NOT remove the attachment post, post meta and file.

                                                                                                                                                            +
                                                                                                                                                            $attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));
                                                                                                                                                            +  $postId = $I->havePostInDatabase();
                                                                                                                                                            +  // Attach the thumbnail to the post.
                                                                                                                                                            +  $I->havePostThumbnailInDatabase($postId, $attachmentId);
                                                                                                                                                            +  // Remove the thumbnail from the post.
                                                                                                                                                            +  $I->dontHavePostThumbnailInDatabase($postId);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $postId - The post ID to remove the thumbnail (featured image) from.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveSiteOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a site option from the database.

                                                                                                                                                            +
                                                                                                                                                            // Remove the `foo_count` option.
                                                                                                                                                            +  $I->dontHaveSiteOptionInDatabase('foo_count');
                                                                                                                                                            +  // Remove the `foo_count` option only if its value is `23`.
                                                                                                                                                            +  $I->dontHaveSiteOptionInDatabase('foo_count', 23);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The option name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed/null $value - If set the option will only be removed it its value matches the specified one.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveSiteTransientInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a site transient from the database.

                                                                                                                                                            +
                                                                                                                                                            $I->dontHaveSiteTransientInDatabase(['my_plugin_site_buffer']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The name of the transient to delete.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveTableInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a table from the database. The case where a table does not exist is handled without raising an error.

                                                                                                                                                            +
                                                                                                                                                            $ordersTable = $I->grabPrefixedTableNameFor('orders');
                                                                                                                                                            +  $I->dontHaveTableInDatabase($ordersTable);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $fullTableName - The full table name, including the table prefix.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveTermInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a term from the database.

                                                                                                                                                            +
                                                                                                                                                            $I->dontHaveTermInDatabase(['name' => 'romance']);
                                                                                                                                                            +  $I->dontHaveTermInDatabase(['slug' => 'genre--romance']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            • +
                                                                                                                                                            • bool $purgeMeta - Whether the terms meta should be purged along side with the meta or not.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveTermMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a term meta from the database.

                                                                                                                                                            +
                                                                                                                                                            // Remove the "karma" key.
                                                                                                                                                            +  $I->dontHaveTermMetaInDatabase(['term_id' => $termId, 'meta_key' => 'karma']);
                                                                                                                                                            +  // Remove all meta for the term.
                                                                                                                                                            +  $I->dontHaveTermMetaInDatabase(['term_id' => $termId]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveTermRelationshipInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an entry from the term_relationships table.

                                                                                                                                                            +
                                                                                                                                                            // Remove the relation between a post and a category.
                                                                                                                                                            +  $I->dontHaveTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $ttaxId]);
                                                                                                                                                            +  // Remove all terms for a post.
                                                                                                                                                            +  $I->dontHaveTermMetaInDatabase(['object_id' => $postId]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveTermTaxonomyInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an entry from the term_taxonomy table.

                                                                                                                                                            +
                                                                                                                                                            // Remove a specific term from the genre taxonomy.
                                                                                                                                                            +  $I->dontHaveTermTaxonomyInDatabase(['term_id' => $postId, 'taxonomy' => 'genre']);
                                                                                                                                                            +  // Remove all terms for a taxonomy.
                                                                                                                                                            +  $I->dontHaveTermTaxonomyInDatabase(['taxonomy' => 'genre']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveTransientInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a transient from the database.

                                                                                                                                                            +
                                                                                                                                                            // Removes the `tweets` transient from the database, if set.
                                                                                                                                                            +  $I->dontHaveTransientInDatabase('tweets');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $transient - The name of the transient to delete.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveUserInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a user from the database.

                                                                                                                                                            +
                                                                                                                                                            $bob = $I->haveUserInDatabase('bob');
                                                                                                                                                            +  $alice = $I->haveUserInDatabase('alice');
                                                                                                                                                            +  // Remove Bob's user and meta.
                                                                                                                                                            +  $I->dontHaveUserInDatabase('bob');
                                                                                                                                                            +  // Remove Alice's user but not meta.
                                                                                                                                                            +  $I->dontHaveUserInDatabase($alice);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int/string $userIdOrLogin - The user ID or login name.
                                                                                                                                                            • +
                                                                                                                                                            • bool $purgeMeta - Whether the user meta should be purged alongside the user or not.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveUserInDatabaseWithEmail

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes a user(s) from the database using the user email address.

                                                                                                                                                            +
                                                                                                                                                            $luca = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $userEmail - The email of the user to remove.
                                                                                                                                                            • +
                                                                                                                                                            • bool $purgeMeta - Whether the user meta should be purged alongside the user or not.
                                                                                                                                                            + +

                                                                                                                                                            dontHaveUserMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Removes an entry from the usermeta table.

                                                                                                                                                            +
                                                                                                                                                            // Remove the `karma` user meta for a user.
                                                                                                                                                            +  $I->dontHaveUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);
                                                                                                                                                            +  // Remove all the user meta for a user.
                                                                                                                                                            +  $I->dontHaveUserMetaInDatabase(['user_id' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeAttachmentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that an attachment is not in the database.

                                                                                                                                                            +
                                                                                                                                                            $url = 'https://example.org/images/foo.png';
                                                                                                                                                            +  $I->dontSeeAttachmentInDatabase(['guid' => $url]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeBlogInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a row is not present in the blogs table.

                                                                                                                                                            +
                                                                                                                                                            $I->haveManyBlogsInDatabase(2, ['path' => 'test-{{n}}'], false)
                                                                                                                                                            +  $I->dontSeeBlogInDatabase(['path' => '/test-3/'])
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeCommentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a comment is not in the database. Will look up the "comments" table.

                                                                                                                                                            +
                                                                                                                                                            // Checks for one comment.
                                                                                                                                                            +  $I->dontSeeCommentInDatabase(['comment_ID' => 23]);
                                                                                                                                                            +  // Checks for comments from a user.
                                                                                                                                                            +  $I->dontSeeCommentInDatabase(['user_id' => 89]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - The search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeCommentMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a comment meta value is not in the database. Will look up the "commentmeta" table.

                                                                                                                                                            +
                                                                                                                                                            // Delete a comment `karma` meta.
                                                                                                                                                            +  $I->dontSeeCommentMetaInDatabase(['comment_id' => 23, 'meta_key' => 'karma']);
                                                                                                                                                            +  // Delete all meta for a comment.
                                                                                                                                                            +  $I->dontSeeCommentMetaInDatabase(['comment_id' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeLinkInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a link is not in the links database table.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeLinkInDatabase(['link_url' => 'http://example.com']);
                                                                                                                                                            +  $I->dontSeeLinkInDatabase(['link_url' => 'http://example.com', 'link_name' => 'example']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that an option is not in the database for the current blog. If the value is an object or an array then the serialized option will be checked.

                                                                                                                                                            +
                                                                                                                                                            $I->dontHaveOptionInDatabase('posts_per_page');
                                                                                                                                                            +  $I->dontSeeOptionInDatabase('posts_per_page');
                                                                                                                                                            +  $I->dontSeeOptionInDatabase('posts_per_page', 23);
                                                                                                                                                            +  $I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page']);
                                                                                                                                                            +  $I->dontSeeOptionInDatabase(['option_name' => 'posts_per_page', 'option_value' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/string $criteriaOrName - An array of search criteria or the option name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                                                                                                                            + +

                                                                                                                                                            dontSeePageInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a page is not in the database.

                                                                                                                                                            +
                                                                                                                                                            // Assert a page with an ID does not exist.
                                                                                                                                                            +  $I->dontSeePageInDatabase(['ID' => 23]);
                                                                                                                                                            +  // Assert a page with a slug and ID.
                                                                                                                                                            +  $I->dontSeePageInDatabase(['post_name' => 'test', 'ID' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeePostInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a post is not in the database.

                                                                                                                                                            +
                                                                                                                                                            // Asserts a post with title 'Test' is not in the database.
                                                                                                                                                            +  $I->dontSeePostInDatabase(['post_title' => 'Test']);
                                                                                                                                                            +  // Asserts a post with title 'Test' and content 'Test content' is not in the database.
                                                                                                                                                            +  $I->dontSeePostInDatabase(['post_title' => 'Test', 'post_content' => 'Test content']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeePostMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a post meta value does not exist. If the meta value is an object or an array then the check will be made on its serialized version.

                                                                                                                                                            +
                                                                                                                                                            $postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']]);
                                                                                                                                                            +  $I->dontSeePostMetaInDatabase(['post_id' => $postId, 'meta_key' => 'woot']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeePostWithTermInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a post to term relation does not exist in the database. The method will check the "term_relationships" table.

                                                                                                                                                            +
                                                                                                                                                            $fiction = $I->haveTermInDatabase('fiction', 'genre');
                                                                                                                                                            +  $nonFiction = $I->haveTermInDatabase('non-fiction', 'genre');
                                                                                                                                                            +  $postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);
                                                                                                                                                            +  $I->dontSeePostWithTermInDatabase($postId, $nonFiction['term_taxonomy_id], );
                                                                                                                                                            +  passed this parameter will be interpreted as a `term_id`, else as a
                                                                                                                                                            +  the
                                                                                                                                                            +  term order.
                                                                                                                                                            +  to build a `taxonomy_term_id` from the `term_id`.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $post_id - The post ID.
                                                                                                                                                            • +
                                                                                                                                                            • int $term_taxonomy_id - The term term_id or term_taxonomy_id; if the $taxonomy argument is
                                                                                                                                                            • +
                                                                                                                                                            • int/null $term_order - The order the term applies to the post, defaults to null to not use
                                                                                                                                                            • +
                                                                                                                                                            • string/null $taxonomy - The taxonomy the term_id is for; if passed this parameter will be used
                                                                                                                                                            + +

                                                                                                                                                            dontSeeSiteOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a site option is not in the database.

                                                                                                                                                            +
                                                                                                                                                            // Check that the option is not set in the database.
                                                                                                                                                            +  $I->dontSeeSiteOptionInDatabase('foo_count');
                                                                                                                                                            +  // Check that the option is not set with a specific value.
                                                                                                                                                            +  $I->dontSeeSiteOptionInDatabase('foo_count', 23);
                                                                                                                                                            +  $I->dontSeeSiteOptionInDatabase(['option_name => 'foo_count', 'option_value' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/string $criteriaOrName - An array of search criteria or the option name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeTableInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a table is not in the database.

                                                                                                                                                            +
                                                                                                                                                            $options = $I->grabPrefixedTableNameFor('options');
                                                                                                                                                            +  $I->dontHaveTableInDatabase($options)
                                                                                                                                                            +  $I->dontSeeTableInDatabase($options);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $table - The full table name, including the table prefix.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeTermInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Makes sure a term is not in the database. Looks up both the terms table and the term_taxonomy tables. and the term_taxonomy tables.

                                                                                                                                                            +
                                                                                                                                                            // Asserts a 'fiction' term is not in the database.
                                                                                                                                                            +  $I->dontSeeTermInDatabase(['name' => 'fiction']);
                                                                                                                                                            +  // Asserts a 'fiction' term with slug 'genre--fiction' is not in the database.
                                                                                                                                                            +  $I->dontSeeTermInDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of criteria to search for the term, can be columns from the terms
                                                                                                                                                            + +

                                                                                                                                                            dontSeeTermMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a term meta is not in the database.

                                                                                                                                                            +
                                                                                                                                                            list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
                                                                                                                                                            +  $I->haveTermMetaInDatabase($termId, 'rating', 4);
                                                                                                                                                            +  $I->dontSeeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'average_review']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeTermTaxonomyInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a term taxonomy is not in the database.

                                                                                                                                                            +
                                                                                                                                                            list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
                                                                                                                                                            +  $I->dontSeeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'country']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeUserInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a user is not in the database.

                                                                                                                                                            +
                                                                                                                                                            // Asserts a user does not exist in the database.
                                                                                                                                                            +  $I->dontSeeUserInDatabase(['user_login' => 'luca']);
                                                                                                                                                            +  // Asserts a user with email and login is not in the database.
                                                                                                                                                            +  $I->dontSeeUserInDatabase(['user_login' => 'luca', 'user_email' => 'luca@theaveragedev.com']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeUserMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Check that a user meta value is not in the database.

                                                                                                                                                            +
                                                                                                                                                            // Asserts a user does not have a 'karma' meta assigned.
                                                                                                                                                            +  $I->dontSeeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);
                                                                                                                                                            +  // Asserts no user has any 'karma' meta assigned.
                                                                                                                                                            +  $I->dontSeeUserMetaInDatabase(['meta_key' => 'karma']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            getSiteDomain

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the site domain inferred from the url set in the config.

                                                                                                                                                            +
                                                                                                                                                            $domain = $I->getSiteDomain();
                                                                                                                                                            +  // We should be redirected to the HTTPS version when visiting the HTTP version.
                                                                                                                                                            +  $I->amOnPage('http://' . $domain);
                                                                                                                                                            +  $I->seeCurrentUrlEquals('https://' . $domain);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            getUsersTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the prefixed users table name.

                                                                                                                                                            +
                                                                                                                                                            // Given a `wp_` table prefix returns `wp_users`.
                                                                                                                                                            +  $usersTable = $I->getUsersTableName();
                                                                                                                                                            +  // Given a `wp_` table prefix returns `wp_users`.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $usersTable = $I->getUsersTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabAllFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns all entries matching a criteria from the database.

                                                                                                                                                            +
                                                                                                                                                            $books = $I->grabPrefixedTableNameFor('books');
                                                                                                                                                            +  $I->grabAllFromDatabase($books, 'title', ['genre' => 'fiction']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $table - The table to grab the values from.
                                                                                                                                                            • +
                                                                                                                                                            • string $column - The column to fetch.
                                                                                                                                                            • +
                                                                                                                                                            • \Codeception\Module\array $criteria - The search criteria.
                                                                                                                                                            + +

                                                                                                                                                            grabAttachmentAttachedFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the path, as stored in the database, of an attachment _wp_attached_file meta. The attached file is, usually, an attachment origal file.

                                                                                                                                                            +
                                                                                                                                                            $file = $I->grabAttachmentAttachedFile($attachmentId);
                                                                                                                                                            +  $fileInfo = new SplFileInfo($file);
                                                                                                                                                            +  $I->assertEquals('jpg', $fileInfo->getExtension());
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $attachmentPostId - The attachment post ID.
                                                                                                                                                            + +

                                                                                                                                                            grabAttachmentMetadata

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the metadata array for an attachment post. This is the value of the _wp_attachment_metadata meta.

                                                                                                                                                            +
                                                                                                                                                            $metadata = $I->grabAttachmentMetadata($attachmentId);
                                                                                                                                                            +  $I->assertEquals(['thumbnail', 'medium', 'medium_large'], array_keys($metadata['sizes']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $attachmentPostId - The attachment post ID.
                                                                                                                                                            + +

                                                                                                                                                            grabBlogDomain

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns a blog domain given its ID.

                                                                                                                                                            +
                                                                                                                                                            $blogIds = $I->haveManyBlogsInDatabase(3);
                                                                                                                                                            +  $domains = array_map(function($blogId){
                                                                                                                                                            +  return $I->grabBlogDomain($blogId);
                                                                                                                                                            +  }, $blogIds);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $blogId - The blog ID.
                                                                                                                                                            + +

                                                                                                                                                            grabBlogPath

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Grabs a blog domain from the blogs table.

                                                                                                                                                            +
                                                                                                                                                            $blogId = $I->haveBlogInDatabase('test');
                                                                                                                                                            +  $path = $I->grabBlogDomain($blogId);
                                                                                                                                                            +  $I->amOnSubdomain($path);
                                                                                                                                                            +  $I->amOnPage('/');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $blogId - The blog ID.
                                                                                                                                                            + +

                                                                                                                                                            grabBlogTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the full name of a table for a blog from a multisite installation database.

                                                                                                                                                            +
                                                                                                                                                            $blogOptionTable = $I->grabBlogTableName($blogId, 'option');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $blogId - The blog ID.
                                                                                                                                                            • +
                                                                                                                                                            • string $table - The table name, without table prefix.
                                                                                                                                                            + +

                                                                                                                                                            grabBlogTableNames

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns a list of tables for a blog ID.

                                                                                                                                                            +
                                                                                                                                                            $blogId = $I->haveBlogInDatabase('test');
                                                                                                                                                            +  $tables = $I->grabBlogTableNames($blogId);
                                                                                                                                                            +  $options = array_filter($tables, function($tableName){
                                                                                                                                                            +  return str_pos($tableName, 'options') !== false;
                                                                                                                                                            +  });
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $blogId - The ID of the blog to fetch the tables for.
                                                                                                                                                            + +

                                                                                                                                                            grabBlogTablePrefix

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the table prefix for a blog.

                                                                                                                                                            +
                                                                                                                                                            $blogId = $I->haveBlogInDatabase('test');
                                                                                                                                                            +  $blogTablePrefix = $I->getBlogTablePrefix($blogId);
                                                                                                                                                            +  $blogOrders = $I->blogTablePrefix . 'orders';
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $blogId - The blog ID.
                                                                                                                                                            + +

                                                                                                                                                            grabBlogVersionsTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed blog_versions table name.

                                                                                                                                                            +
                                                                                                                                                            // Assuming a `wp_` table prefix it will return `wp_blog_versions`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabBlogVersionsTableName();
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Assuming a `wp_` table prefix it will return `wp_blog_versions`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabBlogVersionsTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabBlogsTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed blogs table name.

                                                                                                                                                            +
                                                                                                                                                            // Assuming a `wp_` table prefix it will return `wp_blogs`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabBlogsTableName();
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Assuming a `wp_` table prefix it will return `wp_blogs`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabBlogsTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabCommentmetaTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the prefixed comment meta table name.

                                                                                                                                                            +
                                                                                                                                                            // Get all the values of 'karma' for all comments.
                                                                                                                                                            +  $commentMeta = $I->grabCommentmetaTableName();
                                                                                                                                                            +  $I->grabAllFromDatabase($commentMeta, 'meta_value', ['meta_key' => 'karma']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabCommentsTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the comments table name.

                                                                                                                                                            +
                                                                                                                                                            // Will be `wp_comments`.
                                                                                                                                                            +  $comments = $I->grabCommentsTableName();
                                                                                                                                                            +  // Will be `wp_23_comments`.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $comments = $I->grabCommentsTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabLatestEntryByFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the id value of the last table entry.

                                                                                                                                                            +
                                                                                                                                                            $I->haveManyPostsInDatabase();
                                                                                                                                                            +  $postsTable = $I->grabPostsTableName();
                                                                                                                                                            +  $last = $I->grabLatestEntryByFromDatabase($postsTable, 'ID');
                                                                                                                                                            +  items.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $tableName - The table to fetch the last insertion for.
                                                                                                                                                            • +
                                                                                                                                                            • string $idColumn - The column that is used, in the table, to uniquely identify
                                                                                                                                                            + +

                                                                                                                                                            grabLinksTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the prefixed links table name.

                                                                                                                                                            +
                                                                                                                                                            // Given a `wp_` table prefix returns `wp_links`.
                                                                                                                                                            +  $linksTable = $I->grabLinksTableName();
                                                                                                                                                            +  // Given a `wp_` table prefix returns `wp_23_links`.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $linksTable = $I->grabLinksTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabOptionFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets an option value from the database.

                                                                                                                                                            +
                                                                                                                                                            $count = $I->grabOptionFromDatabase('foo_count');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $option_name - The name of the option to grab from the database.
                                                                                                                                                            + +

                                                                                                                                                            grabPostMetaFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the value of one or more post meta values from the database.

                                                                                                                                                            +
                                                                                                                                                            $thumbnail_id = $I->grabPostMetaFromDatabase($postId, '_thumbnail_id', true);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $postId - The post ID.
                                                                                                                                                            • +
                                                                                                                                                            • string $metaKey - The key of the meta to retrieve.
                                                                                                                                                            • +
                                                                                                                                                            • bool $single - Whether to return a single meta value or an array of all available meta values.
                                                                                                                                                            + +

                                                                                                                                                            grabPostmetaTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the prefixed post meta table name.

                                                                                                                                                            +
                                                                                                                                                            // Returns 'wp_postmeta'.
                                                                                                                                                            +  $I->grabPostmetaTableName();
                                                                                                                                                            +  // Returns 'wp_23_postmeta'.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $I->grabPostmetaTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabPostsTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the posts prefixed table name.

                                                                                                                                                            +
                                                                                                                                                            // Given a `wp_` table prefix returns `wp_posts`.
                                                                                                                                                            +  $postsTable = $I->grabPostsTableName();
                                                                                                                                                            +  // Given a `wp_` table prefix returns `wp_23_posts`.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $postsTable = $I->grabPostsTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabPrefixedTableNameFor

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns a prefixed table name for the current blog. If the table is not one to be prefixed (e.g. users) then the proper table name will be returned.

                                                                                                                                                            +
                                                                                                                                                            // Will return wp_users.
                                                                                                                                                            +  $usersTable = $I->grabPrefixedTableNameFor('users');
                                                                                                                                                            +  // Will return wp_options.
                                                                                                                                                            +  $optionsTable = $I->grabPrefixedTableNameFor('options');
                                                                                                                                                            +  // Use a different blog and get its options table.
                                                                                                                                                            +  $I->useBlog(2);
                                                                                                                                                            +  $blogOptionsTable = $I->grabPrefixedTableNameFor('options');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $tableName - The table name, e.g. options.
                                                                                                                                                            + +

                                                                                                                                                            grabRegistrationLogTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed registration_log table name.

                                                                                                                                                            +
                                                                                                                                                            // Assuming a `wp_` table prefix it will return `wp_registration_log`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabRegistrationLogTableName();
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Assuming a `wp_` table prefix it will return `wp_registration_log`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabRegistrationLogTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabSignupsTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed signups table name.

                                                                                                                                                            +
                                                                                                                                                            // Assuming a `wp_` table prefix it will return `wp_signups`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabSignupsTableName();
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Assuming a `wp_` table prefix it will return `wp_signups`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabSignupsTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabSiteMetaTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed sitemeta table name.

                                                                                                                                                            +
                                                                                                                                                            // Assuming a `wp_` table prefix it will return `wp_sitemeta`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabSiteMetaTableName();
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Assuming a `wp_` table prefix it will return `wp_sitemeta`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabSiteMetaTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabSiteOptionFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets a site option from the database.

                                                                                                                                                            +
                                                                                                                                                            $fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The name of the option to read from the database.
                                                                                                                                                            + +

                                                                                                                                                            grabSiteTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed site table name.

                                                                                                                                                            +
                                                                                                                                                            // Assuming a `wp_` table prefix it will return `wp_site`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabSiteTableName();
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Assuming a `wp_` table prefix it will return `wp_site`.
                                                                                                                                                            +  $blogVersionsTable = $I->grabSiteTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabSiteTransientFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets a site transient from the database.

                                                                                                                                                            +
                                                                                                                                                            $I->grabSiteTransientFromDatabase('total_comments');
                                                                                                                                                            +  $I->grabSiteTransientFromDatabase('api_data');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The site transient to fetch the value for, w/o the _site_transient_ prefix.
                                                                                                                                                            + +

                                                                                                                                                            grabSiteUrl

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the current site URL as specified in the module configuration.

                                                                                                                                                            +
                                                                                                                                                            $shopPath = $I->grabSiteUrl('/shop');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - A path that should be appended to the site URL.
                                                                                                                                                            + +

                                                                                                                                                            grabTablePrefix

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the table prefix, namespaced for secondary blogs if selected.

                                                                                                                                                            +
                                                                                                                                                            // Assuming a table prefix of `wp_` it will return `wp_`;
                                                                                                                                                            +  $tablePrefix = $I->grabTablePrefix();
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Assuming a table prefix of `wp_` it will return `wp_23_`;
                                                                                                                                                            +  $tablePrefix = $I->grabTablePrefix();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabTermIdFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets a term ID from the database. Looks up the prefixed terms table, e.g. wp_terms.

                                                                                                                                                            +
                                                                                                                                                            // Return the 'fiction' term 'term_id'.
                                                                                                                                                            +  $termId = $I->grabTermIdFromDatabase(['name' => 'fiction']);
                                                                                                                                                            +  // Get a term ID by more stringent criteria.
                                                                                                                                                            +  $termId = $I->grabTermIdFromDatabase(['name' => 'fiction', 'slug' => 'genre--fiction']);
                                                                                                                                                            +  // Return the 'term_id' of the first term for a group.
                                                                                                                                                            +  $termId = $I->grabTermIdFromDatabase(['term_group' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            grabTermMetaTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the terms meta table prefixed name.

                                                                                                                                                            +
                                                                                                                                                            // Returns 'wp_termmeta'.
                                                                                                                                                            +  $I->grabTermMetaTableName();
                                                                                                                                                            +  // Returns 'wp_23_termmeta'.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $I->grabTermMetaTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabTermRelationshipsTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed term relationships table name, e.g. wp_term_relationships.

                                                                                                                                                            +
                                                                                                                                                            $I->grabTermRelationshipsTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabTermTaxonomyIdFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets a term_taxonomy_id from the database. Looks up the prefixed terms_relationships table, e.g. wp_term_relationships.

                                                                                                                                                            +
                                                                                                                                                            // Get the `term_taxonomy_id` for a term and a taxonomy.
                                                                                                                                                            +  $I->grabTermTaxonomyIdFromDatabase(['term_id' => $fictionId, 'taxonomy' => 'genre']);
                                                                                                                                                            +  // Get the `term_taxonomy_id` for the first term with a count of 23.
                                                                                                                                                            +  $I->grabTermTaxonomyIdFromDatabase(['count' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            grabTermTaxonomyTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed term and taxonomy table name, e.g. wp_term_taxonomy.

                                                                                                                                                            +
                                                                                                                                                            // Returns 'wp_term_taxonomy'.
                                                                                                                                                            +  $I->grabTermTaxonomyTableName();
                                                                                                                                                            +  // Returns 'wp_23_term_taxonomy'.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $I->grabTermTaxonomyTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabTermsTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the prefixed terms table name, e.g. wp_terms.

                                                                                                                                                            +
                                                                                                                                                            // Returns 'wp_terms'.
                                                                                                                                                            +  $I->grabTermsTableName();
                                                                                                                                                            +  // Returns 'wp_23_terms'.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $I->grabTermsTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabUserIdFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets the a user ID from the database using the user login.

                                                                                                                                                            +
                                                                                                                                                            $userId = $I->grabUserIdFromDatabase('luca');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $userLogin - The user login name.
                                                                                                                                                            + +

                                                                                                                                                            grabUserMetaFromDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Gets a user meta from the database.

                                                                                                                                                            +
                                                                                                                                                            // Returns a user 'karma' value.
                                                                                                                                                            +  $I->grabUserMetaFromDatabase($userId, 'karma');
                                                                                                                                                            +  // Returns an array, the unserialized version of the value stored in the database.
                                                                                                                                                            +  $I->grabUserMetaFromDatabase($userId, 'api_data');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $userId - The ID of th user to get the meta for.
                                                                                                                                                            • +
                                                                                                                                                            • string $meta_key - The meta key to fetch the value for.
                                                                                                                                                            + +

                                                                                                                                                            grabUsermetaTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the prefixed users meta table name.

                                                                                                                                                            +
                                                                                                                                                            // Given a `wp_` table prefix returns `wp_usermeta`.
                                                                                                                                                            +  $usermetaTable = $I->grabUsermetaTableName();
                                                                                                                                                            +  // Given a `wp_` table prefix returns `wp_usermeta`.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $usermetaTable = $I->grabUsermetaTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabUsersTableName

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the prefixed users table name.

                                                                                                                                                            +
                                                                                                                                                            // Given a `wp_` table prefix returns `wp_users`.
                                                                                                                                                            +  $usersTable = $I->grabUsersTableName();
                                                                                                                                                            +  // Given a `wp_` table prefix returns `wp_users`.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  $usersTable = $I->grabUsersTableName();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            haveAttachmentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Creates the database entries representing an attachment and moves the attachment file to the right location. timestamp that should be used to build the "year/time" uploads sub-folder structure. override the image sizes created by default.

                                                                                                                                                            +
                                                                                                                                                            $file = codecept_data_dir('images/test.png');
                                                                                                                                                            +  $attachmentId = $I->haveAttachmentInDatabase($file);
                                                                                                                                                            +  $image = codecept_data_dir('images/test-2.png');
                                                                                                                                                            +  $lastWeekAttachment = $I->haveAttachmentInDatabase($image, '-1 week');
                                                                                                                                                            +  Requires the WPFilesystem module.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The absolute path to the attachment file.
                                                                                                                                                            • +
                                                                                                                                                            • string/string/int $date - Either a string supported by the strtotime function or a UNIX
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An associative array of values overriding the default ones.
                                                                                                                                                            • +
                                                                                                                                                            • \Codeception\Module\array> $imageSizes - An associative array in the format [ => [,]] to
                                                                                                                                                            + +

                                                                                                                                                            haveBlogInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a blog in the blogs table.

                                                                                                                                                            +
                                                                                                                                                            // Create the `test` subdomain blog.
                                                                                                                                                            +  $blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId]);
                                                                                                                                                            +  // Create the `/test` subfolder blog.
                                                                                                                                                            +  $blogId = $I->haveBlogInDatabase('test', ['administrator' => $userId], false);
                                                                                                                                                            +  or subfolder (`true`)
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $domainOrPath - The subdomain or the path to the be used for the blog.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An array of values to override the defaults.
                                                                                                                                                            • +
                                                                                                                                                            • bool $subdomain - Whether the new blog should be created as a subdomain (true)
                                                                                                                                                            + +

                                                                                                                                                            haveCommentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a comment in the database.

                                                                                                                                                            +
                                                                                                                                                            $I->haveCommentInDatabase($postId, ['comment_content' => 'Test Comment', 'comment_karma' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $comment_post_ID - The id of the post the comment refers to.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $data - The comment data overriding default and random generated values.
                                                                                                                                                            + +

                                                                                                                                                            haveCommentMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a comment meta field in the database. Array and object meta values will be serialized.

                                                                                                                                                            +
                                                                                                                                                            $I->haveCommentMetaInDatabase($commentId, 'api_ID', 23);
                                                                                                                                                            +  // The value will be serialized.
                                                                                                                                                            +  $apiData = ['ID' => 23, 'user' => 89, 'origin' => 'twitter'];
                                                                                                                                                            +  $I->haveCommentMetaInDatabase($commentId, 'api_data', $apiData);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $comment_id - The ID of the comment to insert the meta for.
                                                                                                                                                            • +
                                                                                                                                                            • string $meta_key - The key of the comment meta to insert.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $meta_value - The value of the meta to insert, if serializable it will be serialized.
                                                                                                                                                            + +

                                                                                                                                                            haveLinkInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a link in the database.

                                                                                                                                                            +
                                                                                                                                                            $linkId = $I->haveLinkInDatabase(['link_url' => 'http://example.org']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - The data to insert.
                                                                                                                                                            + +

                                                                                                                                                            haveManyBlogsInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts many blogs in the database. by the count.

                                                                                                                                                            +
                                                                                                                                                            $blogIds = $I->haveManyBlogsInDatabase(3, ['domain' =>'test-{{n}}']);
                                                                                                                                                            +  foreach($blogIds as $blogId){
                                                                                                                                                            +  $I->useBlog($blogId);
                                                                                                                                                            +  $I->haveManuPostsInDatabase(3);
                                                                                                                                                            +  }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $count - The number of blogs to create.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An array of values to override the default ones; {{n}} will be replaced
                                                                                                                                                            • +
                                                                                                                                                            • bool $subdomain - Whether the new blogs should be created as a subdomain or subfolder.
                                                                                                                                                            + +

                                                                                                                                                            haveManyCommentsInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts many comments in the database.

                                                                                                                                                            +
                                                                                                                                                            // Insert 3 random comments for a post.
                                                                                                                                                            +  $I->haveManyCommentsInDatabase(3, $postId);
                                                                                                                                                            +  // Insert 3 random comments for a post.
                                                                                                                                                            +  $I->haveManyCommentsInDatabase(3, $postId, ['comment_content' => 'Comment {{n}}']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $count - The number of comments to insert.
                                                                                                                                                            • +
                                                                                                                                                            • int $comment_post_ID - The comment parent post ID.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An associative array to override the defaults.
                                                                                                                                                            + +

                                                                                                                                                            haveManyLinksInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts many links in the database links table.

                                                                                                                                                            +
                                                                                                                                                            // Insert 3 randomly generated links in the database.
                                                                                                                                                            +  $linkIds = $I->haveManyLinksInDatabase(3);
                                                                                                                                                            +  // Inserts links in the database replacing the `n` placeholder.
                                                                                                                                                            +  $linkIds = $I->haveManyLinksInDatabase(3, ['link_url' => 'http://example.org/test-{{n}}']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $count - The number of links to insert.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - Overrides for the default arguments.
                                                                                                                                                            + +

                                                                                                                                                            haveManyPostsInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts many posts in the database returning their IDs. An array of values to override the defaults. The {{n}} placeholder can be used to have the post count inserted in its place; e.g. Post Title - {{n}} will be set to Post Title - 0 for the first post, Post Title - 1 for the second one and so on. The same applies to meta values as well.

                                                                                                                                                            +
                                                                                                                                                            // Insert 3 random posts.
                                                                                                                                                            +  $I->haveManyPostsInDatabase(3);
                                                                                                                                                            +  // Insert 3 posts with generated titles.
                                                                                                                                                            +  $I->haveManyPostsInDatabase(3, ['post_title' => 'Test post {{n}}']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $count - The number of posts to insert.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides
                                                                                                                                                            + +

                                                                                                                                                            haveManyTermsInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts many terms in the database.

                                                                                                                                                            +
                                                                                                                                                            $terms = $I->haveManyTermsInDatabase(3, 'genre-{{n}}', 'genre');
                                                                                                                                                            +  $termIds = array_column($terms, 0);
                                                                                                                                                            +  $termTaxonomyIds = array_column($terms, 1);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $count - The number of terms to insert.
                                                                                                                                                            • +
                                                                                                                                                            • string $name - The term name template, can include the {{n}} placeholder.
                                                                                                                                                            • +
                                                                                                                                                            • string $taxonomy - The taxonomy to insert the terms for.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An associative array of default overrides.
                                                                                                                                                            + +

                                                                                                                                                            haveManyUsersInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts many users in the database.

                                                                                                                                                            +
                                                                                                                                                            $subscribers = $I->haveManyUsersInDatabase(5, 'user-{{n}}');
                                                                                                                                                            +  $editors = $I->haveManyUsersInDatabase(
                                                                                                                                                            +  5,
                                                                                                                                                            +  'user-{{n}}',
                                                                                                                                                            +  'editor',
                                                                                                                                                            +  ['user_email' => 'user-{{n}}@example.org']
                                                                                                                                                            +  );
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $count - The number of users to insert.
                                                                                                                                                            • +
                                                                                                                                                            • string $user_login - The user login name.
                                                                                                                                                            • +
                                                                                                                                                            • string $role - The user role.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An array of values to override the default ones.
                                                                                                                                                            + +

                                                                                                                                                            haveMenuInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Creates and adds a menu to a theme location in the database.

                                                                                                                                                            +
                                                                                                                                                            list($termId, $termTaxId) = $I->haveMenuInDatabase('test', 'sidebar');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $slug - The menu slug.
                                                                                                                                                            • +
                                                                                                                                                            • string $location - The theme menu location the menu will be assigned to.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An array of values to override the defaults.
                                                                                                                                                            + +

                                                                                                                                                            haveMenuItemInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Adds a menu element to a menu for the current theme. post meta.

                                                                                                                                                            +
                                                                                                                                                            $I->haveMenuInDatabase('test', 'sidebar');
                                                                                                                                                            +  $I->haveMenuItemInDatabase('test', 'Test one', 0);
                                                                                                                                                            +  $I->haveMenuItemInDatabase('test', 'Test two', 1);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $menuSlug - The menu slug the item should be added to.
                                                                                                                                                            • +
                                                                                                                                                            • string $title - The menu item title.
                                                                                                                                                            • +
                                                                                                                                                            • int/null $menuOrder - An optional menu order, 1 based.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $meta - An associative array that will be prefixed with _menu_item_ for the item
                                                                                                                                                            + +

                                                                                                                                                            haveOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts an option in the database.

                                                                                                                                                            +
                                                                                                                                                            $I->haveOptionInDatabase('posts_per_page', 23);
                                                                                                                                                            +  $I->haveOptionInDatabase('my_plugin_options', ['key_one' => 'value_one', 'key_two' => 89]);
                                                                                                                                                            +  If the option value is an object or an array then the value will be serialized.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $option_name - The option name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $option_value - The option value; if an array or object it will be serialized.
                                                                                                                                                            • +
                                                                                                                                                            • string $autoload - Weather the option should be autoloaded by WordPress or not.
                                                                                                                                                            + +

                                                                                                                                                            havePageInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a page in the database.

                                                                                                                                                            +
                                                                                                                                                            // Creates a test page in the database with random values.
                                                                                                                                                            +  $randomPageId = $I->havePageInDatabase();
                                                                                                                                                            +  // Creates a test page in the database defining its title.
                                                                                                                                                            +  $testPageId = $I->havePageInDatabase(['post_title' => 'Test page']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An array of values to override the default ones.
                                                                                                                                                            + +

                                                                                                                                                            havePostInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a post in the database. values.

                                                                                                                                                            +
                                                                                                                                                            // Insert a post with random values in the database.
                                                                                                                                                            +  $randomPostId = $I->havePostInDatabase();
                                                                                                                                                            +  // Insert a post with specific values in the database.
                                                                                                                                                            +  $I->havePostInDatabase([
                                                                                                                                                            +  'post_type' => 'book',
                                                                                                                                                            +  'post_title' => 'Alice in Wonderland',
                                                                                                                                                            +  'meta_input' => [
                                                                                                                                                            +  'readers_count' => 23
                                                                                                                                                            +  ],
                                                                                                                                                            +  'tax_input' => [
                                                                                                                                                            +  ['genre' => 'fiction']
                                                                                                                                                            +  ]
                                                                                                                                                            +  ]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • array/\Codeception\Module\array/array $data - An associative array of post data to override default and random generated
                                                                                                                                                            + +

                                                                                                                                                            havePostThumbnailInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Assigns the specified attachment ID as thumbnail (featured image) to a post.

                                                                                                                                                            +
                                                                                                                                                            $attachmentId = $I->haveAttachmentInDatabase(codecept_data_dir('some-image.png'));
                                                                                                                                                            +  $postId = $I->havePostInDatabase();
                                                                                                                                                            +  $I->havePostThumbnailInDatabase($postId, $attachmentId);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $postId - The post ID to assign the thumbnail (featured image) to.
                                                                                                                                                            • +
                                                                                                                                                            • int $thumbnailId - The post ID of the attachment.
                                                                                                                                                            + +

                                                                                                                                                            havePostmetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Adds one or more meta key and value couples in the database for a post.

                                                                                                                                                            +
                                                                                                                                                            // Set the post-meta for a post.
                                                                                                                                                            +  $I->havePostmetaInDatabase($postId, 'karma', 23);
                                                                                                                                                            +  // Set an array post-meta for a post, it will be serialized in the db.
                                                                                                                                                            +  $I->havePostmetaInDatabase($postId, 'data', ['one', 'two']);
                                                                                                                                                            +  // Use a loop to insert one meta per row.
                                                                                                                                                            +  foreach( ['one', 'two'] as $value){
                                                                                                                                                            +  $I->havePostmetaInDatabase($postId, 'data', $value);
                                                                                                                                                            +  }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $postId - The post ID.
                                                                                                                                                            • +
                                                                                                                                                            • string $meta_key - The meta key.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $meta_value - The value to insert in the database, objects and arrays will be serialized.
                                                                                                                                                            + +

                                                                                                                                                            haveSiteOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a site option in the database. If the value is an array or an object then the value will be serialized.

                                                                                                                                                            +
                                                                                                                                                            $fooCountOptionId = $I->haveSiteOptionInDatabase('foo_count','23');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The name of the option to insert.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $value - The value to insert for the option.
                                                                                                                                                            + +

                                                                                                                                                            haveSiteTransientInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a site transient in the database. If the value is an array or an object then the value will be serialized.

                                                                                                                                                            +
                                                                                                                                                            $I->haveSiteTransientInDatabase('total_comments_count', 23);
                                                                                                                                                            +  // This value will be serialized.
                                                                                                                                                            +  $I->haveSiteTransientInDatabase('api_data', ['user' => 'luca', 'token' => '11ae3ijns-j83']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The key of the site transient to insert, w/o the _site_transient_ prefix.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $value - The value to insert; if serializable the value will be serialized.
                                                                                                                                                            + +

                                                                                                                                                            haveTermInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a term in the database.

                                                                                                                                                            +
                                                                                                                                                            // Insert a random 'genre' term in the database.
                                                                                                                                                            +  $I->haveTermInDatabase('non-fiction', 'genre');
                                                                                                                                                            +  // Insert a term in the database with term meta.
                                                                                                                                                            +  $I->haveTermInDatabase('fiction', 'genre', [
                                                                                                                                                            +  'slug' => 'genre--fiction',
                                                                                                                                                            +  'meta' => [
                                                                                                                                                            +  'readers_count' => 23
                                                                                                                                                            +  ]
                                                                                                                                                            +  ]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $name - The term name, e.g. "Fuzzy".
                                                                                                                                                            • +
                                                                                                                                                            • string $taxonomy - The term taxonomy
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An array of values to override the default ones.
                                                                                                                                                            + +

                                                                                                                                                            haveTermMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a term meta row in the database. Objects and array meta values will be serialized.

                                                                                                                                                            +
                                                                                                                                                            $I->haveTermMetaInDatabase($fictionId, 'readers_count', 23);
                                                                                                                                                            +  // Insert some meta that will be serialized.
                                                                                                                                                            +  $I->haveTermMetaInDatabase($fictionId, 'flags', [3, 4, 89]);
                                                                                                                                                            +  // Use a loop to insert one meta per row.
                                                                                                                                                            +  foreach([3, 4, 89] as $value) {
                                                                                                                                                            +  $I->haveTermMetaInDatabase($fictionId, 'flag', $value);
                                                                                                                                                            +  }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $term_id - The ID of the term to insert the meta for.
                                                                                                                                                            • +
                                                                                                                                                            • string $meta_key - The key of the meta to insert.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $meta_value - The value of the meta to insert, if serializable it will be serialized.
                                                                                                                                                            + +

                                                                                                                                                            haveTermRelationshipInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Creates a term relationship in the database. No check about the consistency of the insertion is made. E.g. a post could be assigned a term from a taxonomy that's not registered for that post type.

                                                                                                                                                            +
                                                                                                                                                            // Assign the `fiction` term to a book.
                                                                                                                                                            +  $I->haveTermRelationshipInDatabase($bookId, $fictionId);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $object_id - A post ID, a user ID or anything that can be assigned a taxonomy term.
                                                                                                                                                            • +
                                                                                                                                                            • int $term_taxonomy_id - The term_taxonomy_id of the term and taxonomy to create a relation with.
                                                                                                                                                            • +
                                                                                                                                                            • int $term_order - Defaults to 0.
                                                                                                                                                            + +

                                                                                                                                                            haveTransientInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a transient in the database. If the value is an array or an object then the value will be serialized. Since the transients are set in the context of tests it's not possible to set an expiration directly.

                                                                                                                                                            +
                                                                                                                                                            // Store an array in the `tweets` transient.
                                                                                                                                                            +  $I->haveTransientInDatabase('tweets', $tweets);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $transient - The transient name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $value - The transient value.
                                                                                                                                                            + +

                                                                                                                                                            haveUserCapabilitiesInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets a user capabilities in the database.

                                                                                                                                                            +
                                                                                                                                                            // Assign one user a role in a blog.
                                                                                                                                                            +  $blogId = $I->haveBlogInDatabase('test');
                                                                                                                                                            +  $editor = $I->haveUserInDatabase('luca', 'editor');
                                                                                                                                                            +  $capsIds = $I->haveUserCapabilitiesInDatabase($editor, [$blogId => 'editor']);
                                                                                                                                                            +  // Assign a user two roles in blog 1.
                                                                                                                                                            +  $capsIds = $I->haveUserCapabilitiesInDatabase($userId, ['editor', 'subscriber']);
                                                                                                                                                            +  // Assign one user different roles in different blogs.
                                                                                                                                                            +  $capsIds = $I->haveUserCapabilitiesInDatabase($userId, [$blogId1 => 'editor', $blogId2 => 'author']);
                                                                                                                                                            +  // Assign a user a role and an additional capability in blog 1.
                                                                                                                                                            +  $I->haveUserCapabilitiesInDatabase($userId, ['editor' => true, 'edit_themes' => true]);
                                                                                                                                                            +  // Assign a user a mix of roles and capabilities in different blogs.
                                                                                                                                                            +  $capsIds = $I->haveUserCapabilitiesInDatabase(
                                                                                                                                                            +  $userId,
                                                                                                                                                            +  [
                                                                                                                                                            +  $blogId1 => ['editor' => true, 'edit_themes' => true],
                                                                                                                                                            +  $blogId2 => ['administrator' => true, 'edit_themes' => false]
                                                                                                                                                            +  ]
                                                                                                                                                            +  );
                                                                                                                                                            +  associative array of blog IDs/roles for a multisite
                                                                                                                                                            +  installation (e.g. `[1 => 'administrator`, 2 =>
                                                                                                                                                            +  'subscriber']`).
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $userId - The ID of the user to set the capabilities of.
                                                                                                                                                            • +
                                                                                                                                                            • string/\Codeception\Module\array/\Codeception\Module\array $role - Either a role string (e.g. administrator),an
                                                                                                                                                            + +

                                                                                                                                                            haveUserInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Inserts a user and its meta in the database. defaults to subscriber. If more than one role is specified, then the first role in the list will be the user primary role and the wp_user_level will be set to that role. in the users and usermeta table.

                                                                                                                                                            +
                                                                                                                                                            // Create an editor user in blog 1 w/ specific email.
                                                                                                                                                            +  $userId = $I->haveUserInDatabase('luca', 'editor', ['user_email' => 'luca@example.org']);
                                                                                                                                                            +  // Create a subscriber user in blog 1.
                                                                                                                                                            +  $subscriberId = $I->haveUserInDatabase('subscriber');
                                                                                                                                                            +  // Create a user editor in blog 1, author in blog 2, administrator in blog 3.
                                                                                                                                                            +  $userWithMeta = $I->haveUserInDatabase('luca',
                                                                                                                                                            +  [
                                                                                                                                                            +  1 => 'editor',
                                                                                                                                                            +  2 => 'author',
                                                                                                                                                            +  3 => 'administrator'
                                                                                                                                                            +  ], [
                                                                                                                                                            +  'user_email' => 'luca@example.org'
                                                                                                                                                            +  'meta' => ['a meta_key' => 'a_meta_value']
                                                                                                                                                            +  ]
                                                                                                                                                            +  );
                                                                                                                                                            +  // Create editor in blog 1 w/ `edit_themes` cap, author in blog 2, admin in blog 3 w/o `manage_options` cap.
                                                                                                                                                            +  $userWithMeta = $I->haveUserInDatabase('luca',
                                                                                                                                                            +  [
                                                                                                                                                            +  1 => ['editor', 'edit_themes'],
                                                                                                                                                            +  2 => 'author',
                                                                                                                                                            +  3 => ['administrator' => true, 'manage_options' => false]
                                                                                                                                                            +  ]
                                                                                                                                                            +  );
                                                                                                                                                            +  // Create a user w/o role.
                                                                                                                                                            +  $userId = $I->haveUserInDatabase('luca', '');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $user_login - The user login name.
                                                                                                                                                            • +
                                                                                                                                                            • string/string/\Codeception\Module\array $role - The user role slug(s), e.g. administrator or ['author', 'editor'];
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $overrides - An associative array of column names and values overriding defaults
                                                                                                                                                            + +

                                                                                                                                                            haveUserLevelsInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets the user access level meta in the database for a user. IDs/roles for a multisite installation (e.g. [1 => 'administrator, 2 => 'subscriber']`).

                                                                                                                                                            +
                                                                                                                                                            $userId = $I->haveUserInDatabase('luca', 'editor');
                                                                                                                                                            +  $moreThanAnEditorLessThanAnAdmin = 8;
                                                                                                                                                            +  $I->haveUserLevelsInDatabase($userId, $moreThanAnEditorLessThanAnAdmin);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $userId - The ID of the user to set the level for.
                                                                                                                                                            • +
                                                                                                                                                            • \Codeception\Module\array/string $role - Either a role string (e.g. administrator) or an array of blog
                                                                                                                                                            + +

                                                                                                                                                            haveUserMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets a user meta in the database.

                                                                                                                                                            +
                                                                                                                                                            $userId = $I->haveUserInDatabase('luca', 'editor');
                                                                                                                                                            +  $I->haveUserMetaInDatabase($userId, 'karma', 23);
                                                                                                                                                            +  values will trigger the insertion of multiple rows.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $userId - The user ID.
                                                                                                                                                            • +
                                                                                                                                                            • string $meta_key - The meta key to set the value for.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $meta_value - Either a single value or an array of values; objects will be serialized while array of
                                                                                                                                                            + +

                                                                                                                                                            importSql

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Loads a set SQL code lines in the current database.

                                                                                                                                                            +
                                                                                                                                                            // Import a SQL string.
                                                                                                                                                            +  $I->importSql([$sqlString]);
                                                                                                                                                            +  // Import a set of SQL strings.
                                                                                                                                                            +  $I->importSql($sqlStrings);
                                                                                                                                                            +  // Import a prepared set of SQL strings.
                                                                                                                                                            +  $preparedSqlStrings = array_map(function($line){
                                                                                                                                                            +  return str_replace('{{date}}', date('Y-m-d H:i:s'), $line);
                                                                                                                                                            +  }, $sqlTemplate);
                                                                                                                                                            +  $I->importSql($preparedSqlStrings);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $sql - The SQL strings to load.
                                                                                                                                                            + +

                                                                                                                                                            importSqlDumpFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Import the SQL dump file if populate is enabled.

                                                                                                                                                            +
                                                                                                                                                            // Import a dump file passing the absolute path.
                                                                                                                                                            +  $I->importSqlDumpFile(codecept_data_dir('dumps/start.sql'));
                                                                                                                                                            +  Specifying a dump file that file will be imported.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/null $dumpFile - The dump file that should be imported in place of the default one.
                                                                                                                                                            + +

                                                                                                                                                            seeAttachmentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for an attachment in the database.

                                                                                                                                                            +
                                                                                                                                                            $url = 'https://example.org/images/foo.png';
                                                                                                                                                            +  $I->seeAttachmentInDatabase(['guid' => $url]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeBlogInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a blog in the blogs table.

                                                                                                                                                            +
                                                                                                                                                            // Search for a blog by `blog_id`.
                                                                                                                                                            +  $I->seeBlogInDatabase(['blog_id' => 23]);
                                                                                                                                                            +  // Search for all blogs on a path.
                                                                                                                                                            +  $I->seeBlogInDatabase(['path' => '/sub-path/']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeCommentInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a comment in the database. Will look up the "comments" table.

                                                                                                                                                            +
                                                                                                                                                            $I->seeCommentInDatabase(['comment_ID' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeCommentMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a comment meta value is in the database. Will look up the "commentmeta" table.

                                                                                                                                                            +
                                                                                                                                                            // Assert a specified meta for a comment exists.
                                                                                                                                                            +  $I->seeCommentMetaInDatabase(['comment_ID' => $commentId, 'meta_key' => 'karma', 'meta_value' => 23]);
                                                                                                                                                            +  // Assert the comment has at least one meta set.
                                                                                                                                                            +  $I->seeCommentMetaInDatabase(['comment_ID' => $commentId]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeLinkInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a link in the links table of the database.

                                                                                                                                                            +
                                                                                                                                                            // Asserts a link exists by name.
                                                                                                                                                            +  $I->seeLinkInDatabase(['link_name' => 'my-link']);
                                                                                                                                                            +  // Asserts at least one link exists for the user.
                                                                                                                                                            +  $I->seeLinkInDatabase(['link_owner' => $userId]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks if an option is in the database for the current blog, either by criteria or by name and value. If checking for an array or an object then the serialized version will be checked for.

                                                                                                                                                            +
                                                                                                                                                            // Checks an option is in the database.
                                                                                                                                                            +  $I->seeOptionInDatabase('tables_version');
                                                                                                                                                            +  // Checks an option is in the database and has a specific value.
                                                                                                                                                            +  $I->seeOptionInDatabase('tables_version', '1.0');
                                                                                                                                                            +  $I->seeOptionInDatabase(['option_name' => 'tables_version', 'option_value' => 1.0']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/string $criteriaOrName - An array of search criteria or the option name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                                                                                                                            + +

                                                                                                                                                            seePageInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a page in the database.

                                                                                                                                                            +
                                                                                                                                                            // Asserts a page with an exists in the database.
                                                                                                                                                            +  $I->seePageInDatabase(['ID' => 23]);
                                                                                                                                                            +  // Asserts a page with a slug and ID exists in the database.
                                                                                                                                                            +  $I->seePageInDatabase(['post_title' => 'Test Page', 'ID' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seePostInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a post in the database.

                                                                                                                                                            +
                                                                                                                                                            // Assert a post exists in the database.
                                                                                                                                                            +  $I->seePostInDatabase(['ID' => 23]);
                                                                                                                                                            +  // Assert a post with a slug and ID exists in the database.
                                                                                                                                                            +  $I->seePostInDatabase(['post_content' => 'test content', 'ID' => 23]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seePostMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a post meta value in the database for the current blog. If the meta_value is an object or an array then the check will be made for serialized values.

                                                                                                                                                            +
                                                                                                                                                            $postId = $I->havePostInDatabase(['meta_input' => ['foo' => 'bar']];
                                                                                                                                                            +  $I->seePostMetaInDatabase(['post_id' => '$postId', 'meta_key' => 'foo']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seePostWithTermInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a post to term relation exists in the database. The method will check the "term_relationships" table.

                                                                                                                                                            +
                                                                                                                                                            $fiction = $I->haveTermInDatabase('fiction', 'genre');
                                                                                                                                                            +  $postId = $I->havePostInDatabase(['tax_input' => ['genre' => ['fiction']]]);
                                                                                                                                                            +  $I->seePostWithTermInDatabase($postId, $fiction['term_taxonomy_id']);
                                                                                                                                                            +  passed this parameter will be interpreted as a `term_id`, else as a
                                                                                                                                                            +  the
                                                                                                                                                            +  term order.
                                                                                                                                                            +  to build a `taxonomy_term_id` from the `term_id`.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $post_id - The post ID.
                                                                                                                                                            • +
                                                                                                                                                            • int $term_taxonomy_id - The term term_id or term_taxonomy_id; if the $taxonomy argument is
                                                                                                                                                            • +
                                                                                                                                                            • int/null $term_order - The order the term applies to the post, defaults to null to not use
                                                                                                                                                            • +
                                                                                                                                                            • string/null $taxonomy - The taxonomy the term_id is for; if passed this parameter will be used
                                                                                                                                                            + +

                                                                                                                                                            seeSiteOptionInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a site option is in the database.

                                                                                                                                                            +
                                                                                                                                                            // Check that the option is set in the database.
                                                                                                                                                            +  $I->seeSiteOptionInDatabase('foo_count');
                                                                                                                                                            +  // Check that the option is set and has a specific value.
                                                                                                                                                            +  $I->seeSiteOptionInDatabase('foo_count', 23);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/string $criteriaOrName - An array of search criteria or the option name.
                                                                                                                                                            • +
                                                                                                                                                            • mixed/null $value - The optional value to try and match, only used if the option name is provided.
                                                                                                                                                            + +

                                                                                                                                                            seeSiteSiteTransientInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a site option is in the database.

                                                                                                                                                            +
                                                                                                                                                            // Check a transient exists.
                                                                                                                                                            +  $I->seeSiteSiteTransientInDatabase('total_counts');
                                                                                                                                                            +  // Check a transient exists and has a specific value.
                                                                                                                                                            +  $I->seeSiteSiteTransientInDatabase('total_counts', 23);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $key - The name of the transient to check for, w/o the _site_transient_ prefix.
                                                                                                                                                            • +
                                                                                                                                                            • mixed/null $value - If provided then the assertion will include the value.
                                                                                                                                                            + +

                                                                                                                                                            seeTableInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a table is in the database.

                                                                                                                                                            +
                                                                                                                                                            $options = $I->grabPrefixedTableNameFor('options');
                                                                                                                                                            +  $I->seeTableInDatabase($options);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $table - The full table name, including the table prefix.
                                                                                                                                                            + +

                                                                                                                                                            seeTermInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a term in the database. Looks up the terms and term_taxonomy prefixed tables. and the term_taxonomy tables.

                                                                                                                                                            +
                                                                                                                                                            $I->seeTermInDatabase(['slug' => 'genre--fiction']);
                                                                                                                                                            +  $I->seeTermInDatabase(['name' => 'Fiction', 'slug' => 'genre--fiction']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of criteria to search for the term, can be columns from the terms
                                                                                                                                                            + +

                                                                                                                                                            seeTermMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a term meta in the database.

                                                                                                                                                            +
                                                                                                                                                            list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
                                                                                                                                                            +  $I->haveTermMetaInDatabase($termId, 'rating', 4);
                                                                                                                                                            +  $I->seeTermMetaInDatabase(['term_id' => $termId,'meta_key' => 'rating', 'meta_value' => 4]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeTermRelationshipInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a term relationship in the database.

                                                                                                                                                            +
                                                                                                                                                            $postId = $I->havePostInDatabase(['tax_input' => ['category' => 'one']]);
                                                                                                                                                            +  $I->seeTermRelationshipInDatabase(['object_id' => $postId, 'term_taxonomy_id' => $oneTermTaxId]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeTermTaxonomyInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a taxonomy taxonomy in the database.

                                                                                                                                                            +
                                                                                                                                                            list($termId, $termTaxonomyId) = $I->haveTermInDatabase('fiction', 'genre');
                                                                                                                                                            +  $I->seeTermTaxonomyInDatabase(['term_id' => $termId, 'taxonomy' => 'genre']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeUserInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a user is in the database. The method will check the "users" table.

                                                                                                                                                            +
                                                                                                                                                            $I->seeUserInDatabase([
                                                                                                                                                            +  "user_email" => "test@example.org",
                                                                                                                                                            +  "user_login" => "login name"
                                                                                                                                                            +  ])
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            seeUserMetaInDatabase

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks for a user meta value in the database.

                                                                                                                                                            +
                                                                                                                                                            $I->seeUserMetaInDatabase(['user_id' => 23, 'meta_key' => 'karma']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \Codeception\Module\array/array $criteria - An array of search criteria.
                                                                                                                                                            + +

                                                                                                                                                            useBlog

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets the blog to be used. This has nothing to do with WordPress switch_to_blog function, this code will affect the table prefixes used.

                                                                                                                                                            +
                                                                                                                                                            // Switch to the blog with ID 23.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Switch back to the main blog.
                                                                                                                                                            +  $I->useMainBlog();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $blogId - The ID of the blog to use.
                                                                                                                                                            + +

                                                                                                                                                            useMainBlog

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets the current blog to the main one (blog_id 1).

                                                                                                                                                            +
                                                                                                                                                            // Switch to the blog with ID 23.
                                                                                                                                                            +  $I->useBlog(23);
                                                                                                                                                            +  // Switch back to the main blog.
                                                                                                                                                            +  $I->useMainBlog();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            useTheme

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets the current theme options.

                                                                                                                                                            +
                                                                                                                                                            $I->useTheme('twentyseventeen');
                                                                                                                                                            +  $I->useTheme('child-of-twentyseventeen', 'twentyseventeen');
                                                                                                                                                            +  $I->useTheme('acme', 'acme', 'Acme Theme');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $stylesheet - The theme stylesheet slug, e.g. twentysixteen.
                                                                                                                                                            • +
                                                                                                                                                            • string $template - The theme template slug, e.g. twentysixteen, defaults to $stylesheet.
                                                                                                                                                            • +
                                                                                                                                                            • string $themeName - The theme name, e.g. Acme, defaults to the "title" version of
                                                                                                                                                            + +

                                                                                                                                                            This class extends \Codeception\Module\Db

                                                                                                                                                            +

                                                                                                                                                            This class implements \Codeception\Lib\Interfaces\Db

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WPFilesystem/index.html b/v3/modules/WPFilesystem/index.html new file mode 100644 index 000000000..439a62d53 --- /dev/null +++ b/v3/modules/WPFilesystem/index.html @@ -0,0 +1,3771 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPFilesystem - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WPFilesystem module

                                                                                                                                                            +

                                                                                                                                                            This module should be used in acceptance and functional tests, see levels of testing for more information.
                                                                                                                                                            +This module extends the Filesystem module adding WordPress-specific configuration parameters and methods.
                                                                                                                                                            +The module provides methods to read, write and update the WordPress filesystem directly, without relying on WordPress methods, using WordPress functions or triggering WordPress filters.
                                                                                                                                                            +This module also provides methods to scaffold plugins and themes on the fly in the context of tests and auto-remove them after each test.

                                                                                                                                                            +

                                                                                                                                                            Module requirements for Codeception 4.0+

                                                                                                                                                            +

                                                                                                                                                            This module requires the codeception/module-filesystem Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                            +

                                                                                                                                                            To install the package run:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev codeception/module-filesystem:^1.0
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • wpRootFolder required The absolute, or relative to the project root folder, path to the root WordPress installation folder. The WordPress installation root folder is the one that contains the wp-load.php file.
                                                                                                                                                            • +
                                                                                                                                                            • themes - defaults to /wp-content/themes; the path, relative to the the WordPress installation root folder, to the themes folder.
                                                                                                                                                            • +
                                                                                                                                                            • plugins - defaults to /wp-content/plugins; the path, relative to the WordPress installation root folder, to the plugins folder.
                                                                                                                                                            • +
                                                                                                                                                            • mu-plugins - defaults to wp-content/mu-plugins; the path, relative to the WordPress installation root folder, to the must-use plugins folder.
                                                                                                                                                            • +
                                                                                                                                                            • uploads - defaults to /wp-content/uploads; the path, relative to the WordPress installation root folder, to the uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example configuration

                                                                                                                                                            +
                                                                                                                                                            modules:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - WPFilesystem
                                                                                                                                                            +    config:
                                                                                                                                                            +        WPFilesystem:
                                                                                                                                                            +            wpRootFolder: "/var/www/wordpress"
                                                                                                                                                            +
                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            + + +

                                                                                                                                                            amInMuPluginPath

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets the current working folder to a folder in a mu-plugin.

                                                                                                                                                            +
                                                                                                                                                            $I->amInMuPluginPath('mu-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - The path to the folder, relative to the mu-plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            amInPluginPath

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets the current working folder to a folder in a plugin.

                                                                                                                                                            +
                                                                                                                                                            $I->amInPluginPath('my-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - The folder path, relative to the root uploads folder, to change to.
                                                                                                                                                            + +

                                                                                                                                                            amInThemePath

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Sets the current working folder to a folder in a theme.

                                                                                                                                                            +
                                                                                                                                                            $I->amInThemePath('my-theme');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - The path to the theme folder, relative to themes root folder.
                                                                                                                                                            + +

                                                                                                                                                            amInUploadsPath

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Enters, changing directory, to the uploads folder in the local filesystem.

                                                                                                                                                            +
                                                                                                                                                            $I->amInUploadsPath('/logs');
                                                                                                                                                            +  $I->seeFileFound('shop.log');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - The path, relative to the site uploads folder.
                                                                                                                                                            + +

                                                                                                                                                            cleanMuPluginDir

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Cleans, emptying it, a folder in a mu-plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->cleanMuPluginDir('mu-plugin1/foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $dir - The path to the directory, relative to the mu-plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            cleanPluginDir

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Cleans, emptying it, a folder in a plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->cleanPluginDir('my-plugin/foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $dir - The path to the folder, relative to the plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            cleanThemeDir

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Clears, emptying it, a folder in a theme folder.

                                                                                                                                                            +
                                                                                                                                                            $I->cleanThemeDir('my-theme/foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $dir - The path to the folder, relative to the themese root folder.
                                                                                                                                                            + +

                                                                                                                                                            cleanUploadsDir

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Clears a folder in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->cleanUploadsDir('some/folder');
                                                                                                                                                            +  $I->cleanUploadsDir('some/folder', 'today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $dir - The path to the directory to delete, relative to the uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            • string/int/[\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                            + +

                                                                                                                                                            copyDirToMuPlugin

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Copies a folder to a folder in a mu-plugin.

                                                                                                                                                            +
                                                                                                                                                            $I->copyDirToMuPlugin(codecept_data_dir('foo'), 'mu-plugin/foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $src - The path to the source file to copy.
                                                                                                                                                            • +
                                                                                                                                                            • string $pluginDst - The path to the destination folder, relative to the mu-plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            copyDirToPlugin

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Copies a folder to a folder in a plugin.

                                                                                                                                                            +
                                                                                                                                                            // Copy the 'foo' folder to the 'foo' folder in the plugin.
                                                                                                                                                            +  $I->copyDirToPlugin(codecept_data_dir('foo'), 'my-plugin/foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $src - The path to the source directory to copy.
                                                                                                                                                            • +
                                                                                                                                                            • string $pluginDst - The destination path, relative to the plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            copyDirToTheme

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Copies a folder in a theme folder.

                                                                                                                                                            +
                                                                                                                                                            $I->copyDirToTheme(codecept_data_dir('foo'), 'my-theme');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $src - The path to the source file.
                                                                                                                                                            • +
                                                                                                                                                            • string $themeDst - The path to the destination folder, relative to the themes root folder.
                                                                                                                                                            + +

                                                                                                                                                            copyDirToUploads

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Copies a folder to the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo');
                                                                                                                                                            +  $I->copyDirToUploads(codecept_data_dir('foo'), 'uploadsFoo', 'today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $src - The path to the source file, relative to the current uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $dst - The path to the destination file, relative to the current uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            • string/int/[\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                            + +

                                                                                                                                                            deleteMuPluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Deletes a file in a mu-plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->deleteMuPluginFile('mu-plugin1/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the mu-plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            deletePluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Deletes a file in a plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->deletePluginFile('my-plugin/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The folder path, relative to the plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            deleteThemeFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Deletes a file in a theme folder.

                                                                                                                                                            +
                                                                                                                                                            $I->deleteThemeFile('my-theme/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file to delete, relative to the themes root folder.
                                                                                                                                                            + +

                                                                                                                                                            deleteUploadedDir

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Deletes a dir in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->deleteUploadedDir('folder');
                                                                                                                                                            +  $I->deleteUploadedDir('folder', 'today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $dir - The path to the directory to delete, relative to the uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            • string/int/[\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                            + +

                                                                                                                                                            deleteUploadedFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Deletes a file in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->deleteUploadedFile('some-file.txt');
                                                                                                                                                            +  $I->deleteUploadedFile('some-file.txt', 'today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                            • +
                                                                                                                                                            • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeInMuPluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in a mu-plugin folder does not contain a string.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the mu-plugins root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The contents to check the file for.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeInPluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in a plugin folder does not contain a string.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeInPluginFile('my-plugin/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The contents to check the file for.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeInThemeFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in a theme folder does not contain a string.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeInThemeFile('my-theme/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The contents to check the file for.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeInUploadedFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in the uploads folder does contain a string. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeInUploadedFile('some-file.txt', 'foo');
                                                                                                                                                            +  $I->dontSeeInUploadedFile('some-file.txt','foo', 'today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The not expected file contents or part of them.
                                                                                                                                                            • +
                                                                                                                                                            • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeMuPluginFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file is not found in a mu-plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeMuPluginFileFound('mu-plugin1/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the mu-plugins folder.
                                                                                                                                                            + +

                                                                                                                                                            dontSeePluginFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file is not found in a plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeePluginFileFound('my-plugin/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeThemeFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file is not found in a theme folder.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeThemeFileFound('my-theme/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                            + +

                                                                                                                                                            dontSeeUploadedFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks thata a file does not exist in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->dontSeeUploadedFileFound('some-file.txt');
                                                                                                                                                            +  $I->dontSeeUploadedFileFound('some-file.txt','today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                            • +
                                                                                                                                                            • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                            + +

                                                                                                                                                            getBlogUploadsPath

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the absolute path to a blog uploads folder or file.

                                                                                                                                                            +
                                                                                                                                                            $blogId = $I->haveBlogInDatabase('test');
                                                                                                                                                            +  $testTodayUploads = $I->getBlogUploadsPath($blogId);
                                                                                                                                                            +  $testLastMonthLogs = $I->getBlogUploadsPath($blogId, '/logs', '-1 month');
                                                                                                                                                            +  file or folder.
                                                                                                                                                            +  sub-folders in the year/month format; a UNIX timestamp or
                                                                                                                                                            +  a string supported by the `strtotime` function; defaults
                                                                                                                                                            +  to `now`.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $blogId - The blog ID to get the path for.
                                                                                                                                                            • +
                                                                                                                                                            • string $file - The path, relatitve to the blog uploads folder, to the
                                                                                                                                                            • +
                                                                                                                                                            • null/string/[\DateTime](http://php.net/manual/en/class.datetime.php)/[\DateTime](http://php.net/manual/en/class.datetime.php)Immutable $date - The date that should be used to build the uploads
                                                                                                                                                            + +

                                                                                                                                                            getUploadsPath

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the path to the specified uploads file of folder. Not providing a value for $file and $date will return the uploads folder path.

                                                                                                                                                            +
                                                                                                                                                            $todaysPath = $I->getUploadsPath();
                                                                                                                                                            +  $lastWeek = $I->getUploadsPath('', '-1 week');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The file path, relative to the uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            • mixed $date - A string compatible with strtotime, a Unix timestamp or a Date object.
                                                                                                                                                            + +

                                                                                                                                                            getWpRootFolder

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the absolute path to WordPress root folder without trailing slash.

                                                                                                                                                            +
                                                                                                                                                            $rootFolder = $I->getWpRootFolder();
                                                                                                                                                            +  $I->assertFileExists($rootFolder . 'wp-load.php');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            haveMuPlugin

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Creates a mu-plugin file, including plugin header, in the mu-plugins folder. The code can not contain the opening '<?php' tag.

                                                                                                                                                            +
                                                                                                                                                            $code = 'echo "Hello world!"';
                                                                                                                                                            +  $I->haveMuPlugin('foo-mu-plugin.php', $code);
                                                                                                                                                            +  // Load the code from a file.
                                                                                                                                                            +  $code = file_get_contents(codecept_data_dir('code/mu-plugin.php'));
                                                                                                                                                            +  $I->haveMuPlugin('foo-mu-plugin.php', $code);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $filename - The path to the file to create, relative to the plugins root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $code - The content of the plugin file with or without the opening PHP tag.
                                                                                                                                                            + +

                                                                                                                                                            havePlugin

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Creates a plugin file, including plugin header, in the plugins folder. The plugin is just created and not activated; the code can not contain the opening '<?php' tag.

                                                                                                                                                            +
                                                                                                                                                            $code = 'echo "Hello world!"';
                                                                                                                                                            +  $I->havePlugin('foo/plugin.php', $code);
                                                                                                                                                            +  // Load the code from a file.
                                                                                                                                                            +  $code = file_get_contents(codecept_data_dir('code/plugin.php'));
                                                                                                                                                            +  $I->havePlugin('foo/plugin.php', $code);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - The path to the file to create, relative to the plugins folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $code - The content of the plugin file with or without the opening PHP tag.
                                                                                                                                                            + +

                                                                                                                                                            haveTheme

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Creates a theme file structure, including theme style file and index, in the themes folder. The theme is just created and not activated; the code can not contain the opening '<?php' tag.

                                                                                                                                                            +
                                                                                                                                                            $code = 'sayHi();';
                                                                                                                                                            +  $functionsCode  = 'function sayHi(){echo "Hello world";};';
                                                                                                                                                            +  $I->haveTheme('foo', $indexCode, $functionsCode);
                                                                                                                                                            +  // Load the code from a file.
                                                                                                                                                            +  $indexCode = file_get_contents(codecept_data_dir('code/index.php'));
                                                                                                                                                            +  $functionsCode = file_get_contents(codecept_data_dir('code/functions.php'));
                                                                                                                                                            +  $I->haveTheme('foo', $indexCode, $functionsCode);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $folder - The path to the theme to create, relative to the themes root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $indexFileCode - The content of the theme index.php file with or without the opening PHP tag.
                                                                                                                                                            • +
                                                                                                                                                            • string $functionsFileCode - The content of the theme functions.php file with or without the opening PHP tag.
                                                                                                                                                            + +

                                                                                                                                                            makeUploadsDir

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Creates an empty folder in the WordPress installation uploads folder.

                                                                                                                                                            +
                                                                                                                                                            $logsDir = $I->makeUploadsDir('logs/acme');
                                                                                                                                                            +  to create.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - The path, relative to the WordPress installation uploads folder, of the folder
                                                                                                                                                            + +

                                                                                                                                                            openUploadedFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Opens a file in the the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->openUploadedFile('some-file.txt');
                                                                                                                                                            +  $I->openUploadedFile('some-file.txt', 'time');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $filename - The path to the file, relative to the current uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            • string/int/[\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                            + +

                                                                                                                                                            seeInMuPluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in a mu-plugin folder contains a string.

                                                                                                                                                            +
                                                                                                                                                            $I->seeInMuPluginFile('mu-plugin1/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path the file, relative to the mu-plugins root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The contents to check the file for.
                                                                                                                                                            + +

                                                                                                                                                            seeInPluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in a plugin folder contains a string.

                                                                                                                                                            +
                                                                                                                                                            $I->seeInPluginFile('my-plugin/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The contents to check the file for.
                                                                                                                                                            + +

                                                                                                                                                            seeInThemeFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in a theme folder contains a string.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +  $I->seeInThemeFile('my-theme/some-file.txt', 'foo');
                                                                                                                                                            +  ?>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The contents to check the file for.
                                                                                                                                                            + +

                                                                                                                                                            seeInUploadedFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file in the uploads folder contains a string. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->seeInUploadedFile('some-file.txt', 'foo');
                                                                                                                                                            +  $I->seeInUploadedFile('some-file.txt','foo', 'today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $contents - The expected file contents or part of them.
                                                                                                                                                            • +
                                                                                                                                                            • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                            + +

                                                                                                                                                            seeMuPluginFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file is found in a mu-plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->seeMuPluginFileFound('mu-plugin1/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the mu-plugins folder.
                                                                                                                                                            + +

                                                                                                                                                            seePluginFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file is found in a plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->seePluginFileFound('my-plugin/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to thep plugins root folder.
                                                                                                                                                            + +

                                                                                                                                                            seeThemeFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that a file is found in a theme folder.

                                                                                                                                                            +
                                                                                                                                                            $I->seeThemeFileFound('my-theme/some-file.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the themes root folder.
                                                                                                                                                            + +

                                                                                                                                                            seeUploadedFileFound

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks if file exists in the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->seeUploadedFileFound('some-file.txt');
                                                                                                                                                            +  $I->seeUploadedFileFound('some-file.txt','today');
                                                                                                                                                            +  ?>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $filename - The file path, relative to the uploads folder or the current folder.
                                                                                                                                                            • +
                                                                                                                                                            • string/int $date - A string compatible with strtotime or a Unix timestamp.
                                                                                                                                                            + +

                                                                                                                                                            writeToMuPluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Writes a file in a mu-plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->writeToMuPluginFile('mu-plugin1/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the destination file, relative to the mu-plugins root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $data - The data to write to the file.
                                                                                                                                                            + +

                                                                                                                                                            writeToPluginFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Writes a file in a plugin folder.

                                                                                                                                                            +
                                                                                                                                                            $I->writeToPluginFile('my-plugin/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the plugins root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $data - The data to write in the file.
                                                                                                                                                            + +

                                                                                                                                                            writeToThemeFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Writes a string to a file in a theme folder.

                                                                                                                                                            +
                                                                                                                                                            $I->writeToThemeFile('my-theme/some-file.txt', 'foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $file - The path to the file, relative to the themese root folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $data - The data to write to the file.
                                                                                                                                                            + +

                                                                                                                                                            writeToUploadedFile

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Writes a string to a file in the the uploads folder. The date argument can be a string compatible with strtotime or a Unix timestamp that will be used to build the Y/m uploads subfolder path.

                                                                                                                                                            +
                                                                                                                                                            $I->writeToUploadedFile('some-file.txt', 'foo bar');
                                                                                                                                                            +  $I->writeToUploadedFile('some-file.txt', 'foo bar', 'today');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $filename - The path to the destination file, relative to the current uploads folder.
                                                                                                                                                            • +
                                                                                                                                                            • string $data - The data to write to the file.
                                                                                                                                                            • +
                                                                                                                                                            • string/int/[\DateTime](http://php.net/manual/en/class.datetime.php) $date - The date of the uploads to delete, will default to now.
                                                                                                                                                            + +

                                                                                                                                                            This class extends \Codeception\Module\Filesystem

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WPLoader/index.html b/v3/modules/WPLoader/index.html new file mode 100644 index 000000000..1a070c44f --- /dev/null +++ b/v3/modules/WPLoader/index.html @@ -0,0 +1,3400 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPLoader - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WPLoader module

                                                                                                                                                            +

                                                                                                                                                            This module should be used in integration tests, see levels of testing for more information, to bootstrap WordPress code in the context of the tests.
                                                                                                                                                            +Setting the loadOnly parameter to true the module can be additionally used in acceptance and functional tests to access WordPress code in the tests context.
                                                                                                                                                            +This module is a wrapper around the functionalities provided by the WordPress PHPUnit Core test suite, as such it provides the same method and facilities.
                                                                                                                                                            +The parameters provided to the module duplicate the ones used in the WordPress configuration file: the WPLoader module will not bootstrap WordPress using the wp-config.php file, it will define and use its own WordPress configuration built from the module parameters.

                                                                                                                                                            +

                                                                                                                                                            Everything happens in a transaction

                                                                                                                                                            +

                                                                                                                                                            When used to bootstrap and install WordPress (loadOnly: false) exactly as the the WordPress PHPUnit Core test suite it is based on, this module will operate any change to the database in a transaction.
                                                                                                                                                            +This means that, in the context of integration tests, the result of any write or delete operation done during the tests will be rolled back at the end of each test method; this is done for a number of reasons like performance and tests independence.
                                                                                                                                                            +Inspection of the database during tests, e.g. stopping execution using XDebug, will not show any change in the database. +Keep this in mind while trying to debug integration tests using the WPLoader module.
                                                                                                                                                            +When configured to only load WordPress (loadOnly: true) then any database operation will be committed and written to the database.

                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • wpRootFolder required The absolute, or relative to the project root folder, path to the root WordPress installation folder. The WordPress installation root folder is the one that contains the wp-load.php file.
                                                                                                                                                            • +
                                                                                                                                                            • dbName required - The name of the database used by the WordPress installation, same as the DB_NAME constant.
                                                                                                                                                            • +
                                                                                                                                                            • dbHost required - The host of the database used by the WordPress installation, same as the DB_HOST constant. If the database is accessible (as is the case on the latest version of [Local by Flywheel][http://localwp.com]) via unix socket, then the string to insert here should look like this localhost:/path/to/the/mysql.sock.
                                                                                                                                                            • +
                                                                                                                                                            • dbUser required - The user of the database used by the WordPress installation, same as the DB_USER constant.
                                                                                                                                                            • +
                                                                                                                                                            • dbPassword required - The password of the database used by the WordPress installation, same as DB_PASSWORD constant.
                                                                                                                                                            • +
                                                                                                                                                            • loadOnly - defaults to false; whether to only load WordPress, without bootstrapping a fresh installation for tests or not. Read more in the "Using WPLoader in acceptance and functional tests" section. If this parameter is set to true the following parameters will not apply.
                                                                                                                                                            • +
                                                                                                                                                            • isolatedInstall - defaults to true, whether to install and bootstrap the WordPress installation in a secondary PHP thread for thread safety or not. Maintained for back-compatibility purposes with wp-browser first versions: to get a replica of the bootstrap process used by WordPress Core PHPUnit tests leave this to true.
                                                                                                                                                            • +
                                                                                                                                                            • installationTableHandling - defaults to empty; it controls how tables created by WordPress and plugins will be handled during the installation of WordPress during tests. By default tables will be emptied of any content, but some plugins might require tables to be dropped before WordPress is installed and after plugins are activated (this used to be the default behavior). Supported values are drop to drop the tables, empty to just empty the tables and let to do nothing about the tables. If you get errors from database queries while the WPLoader module installs the tests, then try changing this parameter value.
                                                                                                                                                            • +
                                                                                                                                                            • wpDebug - defaults to true, the value the WP_DEBUG constant will be set to.
                                                                                                                                                            • +
                                                                                                                                                            • multisite - defaults to false, the value the MULTISITE constant will be set to.
                                                                                                                                                            • +
                                                                                                                                                            • skipPluggables - defaults to false, if set to true will skip the definition of pluggable functions.
                                                                                                                                                            • +
                                                                                                                                                            • dbCharset - defaults to utf8, the value the DB_CHARSET constant will be set to.
                                                                                                                                                            • +
                                                                                                                                                            • dbCollate - defaults to an empty string, the value the DB_COLLATE constant will be set to.
                                                                                                                                                            • +
                                                                                                                                                            • tablePrefix - defaults to wptests_, the value the $table_prefix variable will be set to.
                                                                                                                                                            • +
                                                                                                                                                            • domain - defaults to example.org, the domain of the WordPress site to scaffold for the tests.
                                                                                                                                                            • +
                                                                                                                                                            • adminEmail - defaults to admin@example.org, the email of the WordPress site to scaffold for the tests.
                                                                                                                                                            • +
                                                                                                                                                            • title - defaults to Test Blog, the title of the WordPress site to scaffolded for the tests.
                                                                                                                                                            • +
                                                                                                                                                            • phpBinary - defaults to php, the PHP binary the host machine will have to use to bootstrap and load the test WordPress installation.
                                                                                                                                                            • +
                                                                                                                                                            • language - defaults to an empty string, the language of the WordPress installation to scaffold.
                                                                                                                                                            • +
                                                                                                                                                            • configFile - defaults to an empty string, an additional configuration file to include before loading WordPress. Any instruction in this fill will run before any WordPress file is included.
                                                                                                                                                            • +
                                                                                                                                                            • contentFolder - defaults to an empty string; the path, relative to the wpRootFolder or absolute, to the content folder if different from the default one or the one defined by the WP_CONTENT_DIR constant; if the WP_CONTENT_DIR constant is defined in a config file (see the configFile parameter) this will be ignored.
                                                                                                                                                            • +
                                                                                                                                                            • pluginsFolder - defaults to an empty string; the path, relative to the wpRootFolder or absolute, to the plugins folder from the wpRootFolder if different from the default one or the one defined by the WP_PLUGIN_DIR constant; if the WP_PLUGIN_DIR constant is defined in a config file (see the configFile parameter) this will be ignored.
                                                                                                                                                            • +
                                                                                                                                                            • plugins - defaults to an empty array; a list of plugins that should be loaded before any test case runs and after mu-plugins have been loaded; these should be defined in the folder/plugin-file.php format.
                                                                                                                                                            • +
                                                                                                                                                            • activateplugins - defaults to an empty array, a list of plugins that will be activated before any test case runs and after wordpress is fully loaded and set up; these should be defined in the folder/plugin-file.php format; when the multisite option is set to true the plugins will be network activated during the installation.
                                                                                                                                                            • +
                                                                                                                                                            • activatePluginsSilently - defaults to an empty array, a list of plugins that will be silently activated, thus not firing the plugins' activation actions, before any test case runs and after wordpress is fully loaded and set up; these should be defined in the folder/plugin-file.php format; when the multisite option is set to true the plugins will be network activated during the installation.
                                                                                                                                                            • +
                                                                                                                                                            • bootstrapActions - defaults to an empty string, a list of actions, static functions or functions that should be called after before any test case runs, after plugins have been loaded and activated; static functions should be defined in the YAML array format: +
                                                                                                                                                              bootstrapActions:
                                                                                                                                                              +    - action_one
                                                                                                                                                              +    - action_two
                                                                                                                                                              +    - [MyClass, myStaticMethod]
                                                                                                                                                              +    - my_function
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              theme - defaults to an empty string, the theme that should be activated for the tests; if a string is passed then both template and stylesheet options will be set to the passed value; if an array is passed then the template and stylesheet will be set in that order:

                                                                                                                                                              +
                                                                                                                                                              theme: my-theme
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              The theme will be set to my-theme.

                                                                                                                                                              +
                                                                                                                                                              theme: [ parent, child ]
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              The template will be set to parent, the stylesheet will be set to child.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            A word of caution: right now the only way to write tests able to take advantage of the suite is to use the WP_UnitTestCase test case class; while the module will load fine and will raise no problems WP_UnitTestCase will take care of handling the database as intended and using another test case class will almost certainly result in an error if the test case defines more than one test method.

                                                                                                                                                            +

                                                                                                                                                            Example configuration

                                                                                                                                                            +
                                                                                                                                                              modules:
                                                                                                                                                            +      enabled:
                                                                                                                                                            +          - WPLoader
                                                                                                                                                            +      config:
                                                                                                                                                            +          WPLoader:
                                                                                                                                                            +              multisite: false
                                                                                                                                                            +              wpRootFolder: "/Users/luca/www/wordpress"
                                                                                                                                                            +              dbName: "wordpress_tests"
                                                                                                                                                            +              dbHost: "localhost"
                                                                                                                                                            +              dbUser: "root"
                                                                                                                                                            +              dbPassword: "password"
                                                                                                                                                            +              isolatedInstall: true
                                                                                                                                                            +              installationTableHandling: drop
                                                                                                                                                            +              tablePrefix: "wptests_"
                                                                                                                                                            +              domain: "wordrpess.localhost"
                                                                                                                                                            +              adminEmail: "admin@wordpress.localhost"
                                                                                                                                                            +              title: "Test Blog"
                                                                                                                                                            +              theme: my-theme
                                                                                                                                                            +              plugins: ['hello.php', 'my-plugin/my-plugin.php']
                                                                                                                                                            +              activatePlugins: ['hello.php', 'my-plugin/my-plugin.php']
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Usage in integration or "WordPress unit" tests

                                                                                                                                                            +

                                                                                                                                                            The most common use of this module is to run integration, or "WordPress unit" tests (see levels of testing for more information).

                                                                                                                                                            +

                                                                                                                                                            As a first step generate a WPTestCase using Codeception command-line utility (see the commands provided by wp-browser):

                                                                                                                                                            +
                                                                                                                                                            codecept generate:wpunit my_suite "Acme\User"
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Codeception will generate the tests/my_suite/Acme/UserTest.php class. +The class extends the Codeception\TestCase\WPTestCase class provided by wp-browser; this looks like a normal PHPUnit test case but has some perks due to it's mixed breed nature.
                                                                                                                                                            +Understanding them might help you work with it:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • WordPress is installed and configured for the tests before the test case is loaded; WordPress defined functions and classes (and those of the plugins and themes loaded with it) will be available in the setUpBeforeClass method.
                                                                                                                                                            • +
                                                                                                                                                            • WordPress is not loaded when PHPUnit will call the data provider methods; this means the post_provider method will generate a function not found exception when the test case runs as the WordPress defined methods are not loaded yet: +
                                                                                                                                                              public function post_provider(){
                                                                                                                                                              +        // `wp_insert_post` is loaded with WordPress and WordPress has not been loaded yet!
                                                                                                                                                              +        return [
                                                                                                                                                              +                [wp_insert_post(['post_title' => 'Test', 'post_status' => 'publish'])]
                                                                                                                                                              +        ];
                                                                                                                                                              +}
                                                                                                                                                              +
                                                                                                                                                              +public function test_posts($post_id){
                                                                                                                                                              +        $this->assertInstanceOf(WP_Post::class, get_post($post_id));
                                                                                                                                                              +}
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • WordPress is reset to an initial known state before each test runs; the database transaction is rolled back to wipe any data and tables you might have manipulated in the tests, the global space is cleaned. See Everything happens in a transaction.
                                                                                                                                                            • +
                                                                                                                                                            • This is a Codeception Unit test, as such it does provide access to the $this->tester property to access the methods defined in other modules loaded in the suite and to Codeception test doubles
                                                                                                                                                            • +
                                                                                                                                                            • This is a PhpUnit test case too; there are way too many testing functions to cover to report them here but, to highlight a few: mocking with Prophecy and the wealth of PHPUnit assertion methods.
                                                                                                                                                            • +
                                                                                                                                                            • This is kind of a WordPress Core suite test case; as such it provides access to its functions and to the often-overlooked static::factory() method; in this instance too there are too many methods to list them all but it's worth noting how easy it is to set up test fixtures with the factory: +
                                                                                                                                                              public function test_post_creation(){
                                                                                                                                                              +        $random_post_id = static::factory()->post->create();
                                                                                                                                                              +
                                                                                                                                                              +        $this->assertInstanceOf(WP_Post::class, get_post($random_post_id));
                                                                                                                                                              +}
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • The factory property can be accessed on the tester property too and will work the same way as if called using static::factory(): +
                                                                                                                                                              public function test_post_creation(){
                                                                                                                                                              +        $random_post_id = $this->tester->factory()->post->create();
                                                                                                                                                              +
                                                                                                                                                              +        $this->assertInstanceOf(WP_Post::class, get_post($random_post_id));
                                                                                                                                                              +}
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            WPLoader to only bootstrap WordPress

                                                                                                                                                            +

                                                                                                                                                            If the need is to just bootstrap the WordPress installation in the context of the tests variable scope then the WPLoader module loadOnly parameter should be set to true; this could be the case for functional tests in need to access WordPress provided methods, functions and values.
                                                                                                                                                            +An example configuration for the module in this mode is this one:

                                                                                                                                                            +
                                                                                                                                                              modules:
                                                                                                                                                            +      enabled:
                                                                                                                                                            +          - WPDb # BEFORE the WPLoader one!
                                                                                                                                                            +          - WPLoader # AFTER the WPDb one!
                                                                                                                                                            +      config:
                                                                                                                                                            +          WPDb:
                                                                                                                                                            +              dsn: 'mysql:host=localhost;dbname=wordpress'
                                                                                                                                                            +              user: 'root'
                                                                                                                                                            +              password: 'password'
                                                                                                                                                            +              dump: 'tests/_data/dump.sql'
                                                                                                                                                            +              populate: true
                                                                                                                                                            +              cleanup: true
                                                                                                                                                            +              waitlock: 10
                                                                                                                                                            +              url: 'http://wordpress.localhost'
                                                                                                                                                            +              urlReplacement: true
                                                                                                                                                            +              tablePrefix: 'wp_'
                                                                                                                                                            +          WPLoader:
                                                                                                                                                            +              loadOnly: true 
                                                                                                                                                            +              wpRootFolder: "/Users/User/www/wordpress"
                                                                                                                                                            +              dbName: "wpress-tests"
                                                                                                                                                            +              dbHost: "localhost"
                                                                                                                                                            +              dbUser: "root"
                                                                                                                                                            +              dbPassword: "root"
                                                                                                                                                            +              domain: "wordpress.localhost"
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            With reference to the table above the module will not take care of the test WordPress installation state before and after the tests, the installed and activated plugins, and theme.
                                                                                                                                                            +The module can be used in conjunction with a WPDb module to provide the tests with a WordPress installation suiting the tests at hand; when doing so please take care to list, in the suite configuration file modules section (see example above) the WPDb module before the WPLoader one.
                                                                                                                                                            +Codeception will initialize the modules in the same order they are listed in the modules section of the suite configuration file and the WPLoader module needs the database to be populated by the WPDb module before it runs! +As an example this is a correct suite configuration: +

                                                                                                                                                            modules:
                                                                                                                                                            +  enabled:
                                                                                                                                                            +      - WPDb # this before...
                                                                                                                                                            +      - WPLoader # ...this one.
                                                                                                                                                            +  config:
                                                                                                                                                            +      WPDb:
                                                                                                                                                            +        # ...
                                                                                                                                                            +      WPLoader:
                                                                                                                                                            +        loadOnly: true
                                                                                                                                                            +        # ... 
                                                                                                                                                            +

                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            + + +

                                                                                                                                                            debugWpActionFinal

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Debugs a single WordPress action final call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                            +
                                                                                                                                                            // Start debugging all WordPress actions final value.
                                                                                                                                                            +  add_action('all', [$this,'debugWpActionFinal']);
                                                                                                                                                            +  // Run some code firing actions and debug them.
                                                                                                                                                            +  // Stop debugging all WordPress actions final value.
                                                                                                                                                            +  remove_action('all', [$this,'debugWpActionFinal']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • mixed $args
                                                                                                                                                            + +

                                                                                                                                                            debugWpActionInitial

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Debugs a single WordPress action initial call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                            +
                                                                                                                                                            // Start debugging all WordPress actions initial value.
                                                                                                                                                            +  add_action('all', [$this,'debugWpActionInitial']);
                                                                                                                                                            +  // Run some code firing actions and debug them.
                                                                                                                                                            +  // Stop debugging all WordPress actions initial value.
                                                                                                                                                            +  remove_action('all', [$this,'debugWpActionInitial']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • mixed $args
                                                                                                                                                            + +

                                                                                                                                                            debugWpFilterFinal

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Debugs a single WordPress filter final call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                            +
                                                                                                                                                            // Start debugging all WordPress filters final value.
                                                                                                                                                            +  add_filter('all', [$this,'debugWpFilterFinal']);
                                                                                                                                                            +  // Run some code firing filters and debug them.
                                                                                                                                                            +  // Stop debugging all WordPress filters final value.
                                                                                                                                                            +  remove_filter('all', [$this,'debugWpFilterFinal']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • mixed $args
                                                                                                                                                            + +

                                                                                                                                                            debugWpFilterInitial

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Debugs a single WordPress filter initial call using Codeception debug functions. The output will show following the selected output verbosity (--debug and -vvv CLI options).

                                                                                                                                                            +
                                                                                                                                                            // Start debugging all WordPress filters initial value.
                                                                                                                                                            +  add_filter('all', [$this,'debugWpFilterInitial']);
                                                                                                                                                            +  // Run some code firing filters and debug them.
                                                                                                                                                            +  // Stop debugging all WordPress filters initial value.
                                                                                                                                                            +  remove_filter('all', [$this,'debugWpFilterInitial']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • mixed $args
                                                                                                                                                            + +

                                                                                                                                                            factory

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Accessor method to get the object storing the factories for things. This methods gives access to the same factories provided by the Core test suite.

                                                                                                                                                            +
                                                                                                                                                            $postId = $I->factory()->post->create();
                                                                                                                                                            +  $userId = $I->factory()->user->create(['role' => 'administrator']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            getContentFolder

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the absolute path to the WordPress content directory.

                                                                                                                                                            +
                                                                                                                                                            $content = $this->getContentFolder();
                                                                                                                                                            +  $themes = $this->getContentFolder('themes');
                                                                                                                                                            +  $twentytwenty = $this->getContentFolder('themes/twentytwenty');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - An optional path to append to the content directory absolute path.
                                                                                                                                                            + +

                                                                                                                                                            getPluginsFolder

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the absolute path to the plugins directory. The value will first look at the WP_PLUGIN_DIR constant, then the pluginsFolder configuration parameter and will, finally, look in the default path from the WordPress root directory.

                                                                                                                                                            +
                                                                                                                                                            $plugins = $this->getPluginsFolder();
                                                                                                                                                            +  $hello = $this->getPluginsFolder('hello.php');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $path - A relative path to append to te plugins directory absolute path.
                                                                                                                                                            + +

                                                                                                                                                            startWpFiltersDebug

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Starts the debug of all WordPress filters and actions. The method hook on all filters and actions to debug their value.

                                                                                                                                                            +
                                                                                                                                                            // Start debugging all WordPress filters and action final and initial values.
                                                                                                                                                            +  $this->startWpFiltersDebug();
                                                                                                                                                            +  // Run some code firing filters and debug them.
                                                                                                                                                            +  // Stop debugging all WordPress filters and action final and initial values.
                                                                                                                                                            +  $this->stopWpFiltersDebug();
                                                                                                                                                            +  the array of arguments as input.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \callable $format - A callback function to format the arguments debug output; the callback will receive
                                                                                                                                                            + +

                                                                                                                                                            stopWpFiltersDebug

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Stops the debug of all WordPress filters and actions.

                                                                                                                                                            +
                                                                                                                                                            // Start debugging all WordPress filters and action final and initial values.
                                                                                                                                                            +  $this->startWpFiltersDebug();
                                                                                                                                                            +  // Run some code firing filters and debug them.
                                                                                                                                                            +  // Stop debugging all WordPress filters and action final and initial values.
                                                                                                                                                            +  $this->stopWpFiltersDebug();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This class extends \Codeception\Module

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WPQueries/index.html b/v3/modules/WPQueries/index.html new file mode 100644 index 000000000..d968f7bf8 --- /dev/null +++ b/v3/modules/WPQueries/index.html @@ -0,0 +1,3722 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPQueries - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WPQueries module

                                                                                                                                                            +

                                                                                                                                                            This module should be used in integration tests, see levels of testing for more information, to make assertions on the database queries made by the global $wpdb object.
                                                                                                                                                            +This module requires the WPLoader module to work.
                                                                                                                                                            +The module will set, if not set already, the SAVEQUERIES constant to true and will throw an exception if the constant is already set to a falsy value.

                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +

                                                                                                                                                            This module does not require any configuration, but requires the WPLoader module to work correctly.

                                                                                                                                                            +

                                                                                                                                                            Usage

                                                                                                                                                            +

                                                                                                                                                            This module must be used in a test case extending the \Codeception\TestCase\WPTestCase class.

                                                                                                                                                            +

                                                                                                                                                            The module public API is accessible calling via the \Codeception\TestCase\WPTestCase::queries() method:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +
                                                                                                                                                            +use Codeception\Module\WPQueries;
                                                                                                                                                            +
                                                                                                                                                            +class WPQueriesUsageTest extends \Codeception\TestCase\WPTestCase
                                                                                                                                                            +{
                                                                                                                                                            +    public function test_queries_made_by_factory_are_not_tracked()
                                                                                                                                                            +    {
                                                                                                                                                            +        $currentQueriesCount = $this->queries()->countQueries();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertNotEmpty($currentQueriesCount);
                                                                                                                                                            +
                                                                                                                                                            +        static::factory()->post->create_many(3);
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertNotEmpty($currentQueriesCount);
                                                                                                                                                            +        $this->assertEquals($currentQueriesCount, $this->queries()->countQueries());
                                                                                                                                                            +    }
                                                                                                                                                            +
                                                                                                                                                            +    public function test_count_queries()
                                                                                                                                                            +    {
                                                                                                                                                            +        $currentQueriesCount = $this->queries()->countQueries();
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertNotEmpty($currentQueriesCount);
                                                                                                                                                            +
                                                                                                                                                            +        foreach (range(1, 3) as $i) {
                                                                                                                                                            +            wp_insert_post(['post_title' => 'Post ' . $i, 'post_content' => str_repeat('test', $i)]);
                                                                                                                                                            +        }
                                                                                                                                                            +
                                                                                                                                                            +        $this->assertNotEmpty($currentQueriesCount);
                                                                                                                                                            +        $this->assertGreaterThan($currentQueriesCount, $this->queries()->countQueries());
                                                                                                                                                            +    }
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            + + +

                                                                                                                                                            assertCountQueries

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries have been made.

                                                                                                                                                            +
                                                                                                                                                            $posts = $this->factory()->post->create_many(3);
                                                                                                                                                            +  $cachedUsers = $this->factory()->user->create_many(2);
                                                                                                                                                            +  $nonCachedUsers = $this->factory()->user->create_many(2);
                                                                                                                                                            +  foreach($cachedUsers as $userId){
                                                                                                                                                            +  wp_cache_set('page-posts-for-user-' . $userId, $posts, 'acme');
                                                                                                                                                            +  }
                                                                                                                                                            +  // Run the same query as different users
                                                                                                                                                            +  foreach(array_merge($cachedUsers, $nonCachedUsers) as $userId){
                                                                                                                                                            +  $pagePosts = $plugin->getPagePostsForUser($userId);
                                                                                                                                                            +  }
                                                                                                                                                            +  $I->assertCountQueries(2, 'A query should be made for each user missing cached posts.')
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueries

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $posts = $this->factory()->post->create_many(3);
                                                                                                                                                            +  wp_cache_set('page-posts', $posts, 'acme');
                                                                                                                                                            +  $pagePosts = $plugin->getPagePosts();
                                                                                                                                                            +  $I->assertNotQueries('Queries should not be made if the cache is set.')
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByAction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made as a consequence of the specified action. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_action( 'edit_post', function($postId){
                                                                                                                                                            +  $count = get_option('acme_title_updates_count');
                                                                                                                                                            +  update_option('acme_title_updates_count', ++$count);
                                                                                                                                                            +  } );
                                                                                                                                                            +  wp_delete_post($bookId);
                                                                                                                                                            +  $this->assertNotQueriesByAction('edit_post');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $action - The action name, e.g. 'init'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByFilter

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made as a consequence of the specified filter. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_filter('the_title', function($title, $postId){
                                                                                                                                                            +  $post = get_post($postId);
                                                                                                                                                            +  if($post->post_type !== 'book'){
                                                                                                                                                            +  return $title;
                                                                                                                                                            +  }
                                                                                                                                                            +  $new = get_option('acme_new_prefix');
                                                                                                                                                            +  return "{$new} - " . $title;
                                                                                                                                                            +  });
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
                                                                                                                                                            +  $this->assertNotQueriesByFilter('the_title');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByFunction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made by the specified function. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $this->assertEmpty(Acme\get_orphaned_posts());
                                                                                                                                                            +  Acme\delete_orphaned_posts();
                                                                                                                                                            +  $this->assertNotQueriesByFunction('Acme\delete_orphaned_posts');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $function - The fully qualified name of the function to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByMethod

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries have been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $options = new Acme\Options();
                                                                                                                                                            +  $options->update('adsSource', 'not-a-real-url.org');
                                                                                                                                                            +  $I->assertNotQueriesByMethod('Acme\Options', 'update');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $class - The fully qualified name of the class to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $method - The name of the method to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByStatement

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries have been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $bookRepository = new Acme\BookRepository();
                                                                                                                                                            +  $repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
                                                                                                                                                            +  $this->assertNotQueriesByStatement('INSERT', 'Deferred write should happen on __destruct');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByStatementAndAction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made as a consequence of the specified action containing the SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_action( 'edit_post', function($postId){
                                                                                                                                                            +  $count = get_option('acme_title_updates_count');
                                                                                                                                                            +  update_option('acme_title_updates_count', ++$count);
                                                                                                                                                            +  } );
                                                                                                                                                            +  wp_delete_post($bookId);
                                                                                                                                                            +  $this->assertNotQueriesByStatementAndAction('DELETE', 'delete_post');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $action - The action name, e.g. 'init'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByStatementAndFilter

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made as a consequence of the specified filter containing the specified SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_filter('the_title', function($title, $postId){
                                                                                                                                                            +  $post = get_post($postId);
                                                                                                                                                            +  if($post->post_type !== 'book'){
                                                                                                                                                            +  return $title;
                                                                                                                                                            +  }
                                                                                                                                                            +  $new = get_option('acme_new_prefix');
                                                                                                                                                            +  return "{$new} - " . $title;
                                                                                                                                                            +  });
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
                                                                                                                                                            +  $this->assertNotQueriesByStatementAndFilter('SELECT', 'the_title');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByStatementAndFunction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            wp_insert_post(['ID' => $bookId, 'post_title' => 'The Call of the Wild']);
                                                                                                                                                            +  $this->assertNotQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
                                                                                                                                                            +  $this->assertQueriesByStatementAndFunction('UPDATE', 'wp_insert_post');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $function - The name of the function to check the assertions for.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertNotQueriesByStatementAndMethod

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that no queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
                                                                                                                                                            +  $this->assertQueriesByStatementAndMethod('INSERT', Acme\BookRepository::class, 'commit');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $class - The fully qualified name of the class to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $method - The name of the method to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueries

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that at least one query was made during the test. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            wp_cache_delete('page-posts', 'acme');
                                                                                                                                                            +  $pagePosts = $plugin->getPagePosts();
                                                                                                                                                            +  $I->assertQueries('Queries should be made to set the cache.')
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByAction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that at least one query was made as a consequence of the specified action. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_action( 'edit_post', function($postId){
                                                                                                                                                            +  $count = get_option('acme_title_updates_count');
                                                                                                                                                            +  update_option('acme_title_updates_count', ++$count);
                                                                                                                                                            +  } );
                                                                                                                                                            +  wp_update_post(['ID' => $bookId, 'post_title' => 'New Title']);
                                                                                                                                                            +  $this->assertQueriesByAction('edit_post');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $action - The action name, e.g. 'init'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByFilter

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that at least one query was made as a consequence of the specified filter. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_filter('the_title', function($title, $postId){
                                                                                                                                                            +  $post = get_post($postId);
                                                                                                                                                            +  if($post->post_type !== 'book'){
                                                                                                                                                            +  return $title;
                                                                                                                                                            +  }
                                                                                                                                                            +  $new = get_option('acme_new_prefix');
                                                                                                                                                            +  return "{$new} - " . $title;
                                                                                                                                                            +  });
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
                                                                                                                                                            +  $this->assertQueriesByFilter('the_title');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByFunction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that queries were made by the specified function. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            acme_clean_queue();
                                                                                                                                                            +  $this->assertQueriesByFunction('acme_clean_queue');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $function - The fully qualified name of the function to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByMethod

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that at least one query has been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $options = new Acme\Options();
                                                                                                                                                            +  $options->update('showAds', false);
                                                                                                                                                            +  $I->assertQueriesByMethod('Acme\Options', 'update');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $class - The fully qualified name of the class to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $method - The name of the method to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByStatement

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that at least a query starting with the specified statement was made. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            wp_cache_flush();
                                                                                                                                                            +  cached_get_posts($args);
                                                                                                                                                            +  $I->assertQueriesByStatement('SELECT');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByStatementAndAction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that at least one query was made as a consequence of the specified action containing the SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_action( 'edit_post', function($postId){
                                                                                                                                                            +  $count = get_option('acme_title_updates_count');
                                                                                                                                                            +  update_option('acme_title_updates_count', ++$count);
                                                                                                                                                            +  } );
                                                                                                                                                            +  wp_update_post(['ID' => $bookId, 'post_title' => 'New']);
                                                                                                                                                            +  $this->assertQueriesByStatementAndAction('UPDATE', 'edit_post');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $action - The action name, e.g. 'init'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByStatementAndFilter

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that at least one query was made as a consequence of the specified filter containing the SQL query. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_filter('the_title', function($title, $postId){
                                                                                                                                                            +  $post = get_post($postId);
                                                                                                                                                            +  if($post->post_type !== 'book'){
                                                                                                                                                            +  return $title;
                                                                                                                                                            +  }
                                                                                                                                                            +  $new = get_option('acme_new_prefix');
                                                                                                                                                            +  return "{$new} - " . $title;
                                                                                                                                                            +  });
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
                                                                                                                                                            +  $this->assertQueriesByStatementAndFilter('SELECT', 'the_title');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByStatementAndFunction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);
                                                                                                                                                            +  $this->assertQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $function - The fully qualified function name.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesByStatementAndMethod

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
                                                                                                                                                            +  $this->assertQueriesByStatementAndMethod('UPDATE', Acme\BookRepository::class, 'commit');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $class - The fully qualified name of the class to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $method - The name of the method to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByAction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries were made as a consequence of the specified action. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_action( 'edit_post', function($postId){
                                                                                                                                                            +  $count = get_option('acme_title_updates_count');
                                                                                                                                                            +  update_option('acme_title_updates_count', ++$count);
                                                                                                                                                            +  } );
                                                                                                                                                            +  wp_update_post(['ID' => $bookOneId, 'post_title' => 'One']);
                                                                                                                                                            +  wp_update_post(['ID' => $bookTwoId, 'post_title' => 'Two']);
                                                                                                                                                            +  wp_update_post(['ID' => $bookThreeId, 'post_title' => 'Three']);
                                                                                                                                                            +  $this->assertQueriesCountByAction(3, 'edit_post');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $action - The action name, e.g. 'init'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByFilter

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries were made as a consequence of the specified filter. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_filter('the_title', function($title, $postId){
                                                                                                                                                            +  $post = get_post($postId);
                                                                                                                                                            +  if($post->post_type !== 'book'){
                                                                                                                                                            +  return $title;
                                                                                                                                                            +  }
                                                                                                                                                            +  $new = get_option('acme_new_prefix');
                                                                                                                                                            +  return "{$new} - " . $title;
                                                                                                                                                            +  });
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);
                                                                                                                                                            +  $this->assertQueriesCountByFilter(2, 'the_title');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByFunction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries were made by the specified function. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $this->assertCount(3, Acme\get_orphaned_posts());
                                                                                                                                                            +  Acme\delete_orphaned_posts();
                                                                                                                                                            +  $this->assertQueriesCountByFunction(3, 'Acme\delete_orphaned_posts');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $function - The function to check the queries for.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByMethod

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries have been made by the specified class method. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $bookRepository = new Acme\BookRepository();
                                                                                                                                                            +  $repository->where('ID', 23)->commit('title', 'Peter Pan');
                                                                                                                                                            +  $repository->where('ID', 89)->commit('title', 'Moby-dick');
                                                                                                                                                            +  $repository->where('ID', 2389)->commit('title', 'The call of the wild');
                                                                                                                                                            +  $this->assertQueriesCountByMethod(3, 'Acme\BookRepository', 'commit');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $class - The fully qualified name of the class to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $method - The name of the method to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByStatement

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries starting with the specified statement were made. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            $bookRepository = new Acme\BookRepository();
                                                                                                                                                            +  $repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
                                                                                                                                                            +  $repository->where('ID', 89)->set('title', 'Moby-dick', $deferred = true);
                                                                                                                                                            +  $repository->where('ID', 2389)->set('title', 'The call of the wild', $deferred = false);
                                                                                                                                                            +  $this->assertQueriesCountByStatement(1, 'INSERT', 'Deferred write should happen on __destruct');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByStatementAndAction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries were made as a consequence of the specified action containing the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_action( 'edit_post', function($postId){
                                                                                                                                                            +  $count = get_option('acme_title_updates_count');
                                                                                                                                                            +  update_option('acme_title_updates_count', ++$count);
                                                                                                                                                            +  } );
                                                                                                                                                            +  wp_delete_post($bookOneId);
                                                                                                                                                            +  wp_delete_post($bookTwoId);
                                                                                                                                                            +  wp_update_post(['ID' => $bookThreeId, 'post_title' => 'New']);
                                                                                                                                                            +  $this->assertQueriesCountByStatementAndAction(2, 'DELETE', 'delete_post');
                                                                                                                                                            +  $this->assertQueriesCountByStatementAndAction(1, 'INSERT', 'edit_post');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $action - The action name, e.g. 'init'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByStatementAndFilter

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries were made as a consequence of the specified filter containing the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            add_filter('the_title', function($title, $postId){
                                                                                                                                                            +  $post = get_post($postId);
                                                                                                                                                            +  if($post->post_type !== 'book'){
                                                                                                                                                            +  return $title;
                                                                                                                                                            +  }
                                                                                                                                                            +  $new = get_option('acme_new_prefix');
                                                                                                                                                            +  return "{$new} - " . $title;
                                                                                                                                                            +  });
                                                                                                                                                            +  // Warm up the cache.
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);
                                                                                                                                                            +  // Cache is warmed up now.
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);
                                                                                                                                                            +  $title = apply_filters('the_title', get_post($bookThreeId)->post_title, $bookThreeId);
                                                                                                                                                            +  $this->assertQueriesCountByStatementAndFilter(1, 'SELECT', 'the_title');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $filter - The filter name, e.g. 'posts_where'.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByStatementAndFunction

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            wp_insert_post(['post_type' => 'book', 'post_title' => 'The Call of the Wild']);
                                                                                                                                                            +  wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);
                                                                                                                                                            +  wp_insert_post(['post_type' => 'book', 'post_title' => 'The Chocolate Factory']);
                                                                                                                                                            +  $this->assertQueriesCountByStatementAndFunction(3, 'INSERT', 'wp_insert_post');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $function - The fully-qualified function name.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            assertQueriesCountByStatementAndMethod

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Asserts that n queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp, tearDown and factory methods are excluded by default.

                                                                                                                                                            +
                                                                                                                                                            Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
                                                                                                                                                            +  Acme\BookRepository::new(['title' => 'Moby-Dick'])->commit();
                                                                                                                                                            +  Acme\BookRepository::new(['title' => 'The Call of the Wild'])->commit();
                                                                                                                                                            +  $this->assertQueriesCountByStatementAndMethod(3, 'INSERT', Acme\BookRepository::class, 'commit');
                                                                                                                                                            +  Regular expressions must contain delimiters.
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $n - The expected number of queries.
                                                                                                                                                            • +
                                                                                                                                                            • string $statement - A simple string the statement should start with or a valid regular expression.
                                                                                                                                                            • +
                                                                                                                                                            • string $class - The fully qualified name of the class to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $method - The name of the method to check.
                                                                                                                                                            • +
                                                                                                                                                            • string $message - An optional message to override the default one.
                                                                                                                                                            + +

                                                                                                                                                            countQueries

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the current number of queries. Set-up and tear-down queries performed by the test case are filtered out.

                                                                                                                                                            +
                                                                                                                                                            // In a WPTestCase, using the global $wpdb object.
                                                                                                                                                            +  $queriesCount = $this->queries()->countQueries();
                                                                                                                                                            +  // In a WPTestCase, using a custom $wpdb object.
                                                                                                                                                            +  $queriesCount = $this->queries()->countQueries($customWdbb);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • \wpdb/null $wpdb - A specific instance of the wpdb class or null to use the global one.
                                                                                                                                                            + +

                                                                                                                                                            getQueries

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the queries currently performed by the global database object or the specified one. Set-up and tear-down queries performed by the test case are filtered out.

                                                                                                                                                            +
                                                                                                                                                            // In a WPTestCase, using the global $wpdb object.
                                                                                                                                                            +  $queries = $this->queries()->getQueries();
                                                                                                                                                            +  // In a WPTestCase, using a custom $wpdb object.
                                                                                                                                                            +  $queries = $this->queries()->getQueries($customWdbb);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • null/\wpdb $wpdb - A specific instance of the wpdb class or null to use the global one.
                                                                                                                                                            + +

                                                                                                                                                            This class extends \Codeception\Module

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WPWebDriver/index.html b/v3/modules/WPWebDriver/index.html new file mode 100644 index 000000000..02868df64 --- /dev/null +++ b/v3/modules/WPWebDriver/index.html @@ -0,0 +1,3994 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WPWebDriver - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WpWebDriver module

                                                                                                                                                            +

                                                                                                                                                            This module should be used in acceptance tests, see levels of testing for more information.

                                                                                                                                                            +

                                                                                                                                                            This module extends the WebDriver module adding WordPress-specific configuration parameters and methods.

                                                                                                                                                            +

                                                                                                                                                            The module simulates a user interaction with the site with Javascript support; if you don't need to test your project with Javascript support use the WPBrowser module.

                                                                                                                                                            +

                                                                                                                                                            Module requirements for Codeception 4.0+

                                                                                                                                                            +

                                                                                                                                                            This module requires the codeception/module-webdriver Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                            +

                                                                                                                                                            To install the package run:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev codeception/module-webdriver:^1.0
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +

                                                                                                                                                            Due to the combination of possible browsers, capabilities and configurations, it's not possible to provide an exhaustive coverage of all the possible configuration parameteters here.

                                                                                                                                                            +

                                                                                                                                                            Please refer to WebDriver documentation for more information.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • url required - Start URL of your WordPress project, e.g. http://wp.test.
                                                                                                                                                            • +
                                                                                                                                                            • adminUsername required - This is the login name, not the "nice" name, of the administrator user of the WordPress test site. This will be used to fill the username field in WordPress login page.
                                                                                                                                                            • +
                                                                                                                                                            • adminPassword required - This is the the password of the administrator use of the WordPress test site. This will be used to fill the password in WordPress login page.
                                                                                                                                                            • +
                                                                                                                                                            • adminPath required - The path, relative to the WordPress test site home URL, to the administration area, usually /wp-admin.
                                                                                                                                                            • +
                                                                                                                                                            • browser - The browser to use for the tests, e.g. chrome or firefox.
                                                                                                                                                            • +
                                                                                                                                                            • capabilities - Depending on the browser set in browser this is a list of browser-specific capabilities.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example configuration

                                                                                                                                                            +
                                                                                                                                                            modules:
                                                                                                                                                            +  enabled:
                                                                                                                                                            +    - WPWebDriver
                                                                                                                                                            +  config:
                                                                                                                                                            +    WPWebDriver:
                                                                                                                                                            +      url: 'http://wp.test'
                                                                                                                                                            +      adminUsername: 'admin'
                                                                                                                                                            +      adminPassword: 'password'
                                                                                                                                                            +      adminPath: '/wp-admin'
                                                                                                                                                            +      browser: chrome
                                                                                                                                                            +      host: localhost
                                                                                                                                                            +      port: 4444
                                                                                                                                                            +      window_size: false #disabled for Chrome driver
                                                                                                                                                            +      capabilities:
                                                                                                                                                            +        "goog:chromeOptions":
                                                                                                                                                            +          args:
                                                                                                                                                            +            - "--headless"
                                                                                                                                                            +            - "--disable-gpu"
                                                                                                                                                            +            - "--disable-dev-shm-usage"
                                                                                                                                                            +            - "--proxy-server='direct://'"
                                                                                                                                                            +            - "--proxy-bypass-list=*"
                                                                                                                                                            +            - "--no-sandbox"
                                                                                                                                                            +
                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              acceptPopup() : void
                                                                                                                                                              + Accepts the active JavaScript native popup window, as created by window.alert|window.confirm|window.prompt. + Don't confuse popups with modal windows, + as created by various libraries.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              activatePlugin($pluginSlug) : void
                                                                                                                                                              + In the plugin administration screen activates one or more plugins clicking the "Activate" link.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugins administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • activateTheme($slug) : void
                                                                                                                                                              + Activates a theme.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amEditingPostWithId($id) : void
                                                                                                                                                              + Go to the admin page to edit the post with the specified ID.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication the admin area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amEditingUserWithId($id) : void
                                                                                                                                                              + Go to the admin page to edit the user with the specified ID.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication the admin area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amOnAdminAjaxPage([$queryVars]) : void
                                                                                                                                                              + Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication, nonces or authorization.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amOnAdminPage($page) : void
                                                                                                                                                              + Go to a page in the admininstration area of the site.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            This method will not handle authentication to the administration area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              amOnCronPage([$queryVars]) : void
                                                                                                                                                              + Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnPage($page) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnPagesPage() : void
                                                                                                                                                              + Go the "Pages" administration screen.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • amOnPluginsPage() : void
                                                                                                                                                              + Go to the plugins administration screen.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              amOnSubdomain($subdomain) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnThemesPage() : void
                                                                                                                                                              + Moves to the themes administration page.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              amOnUrl($url) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              appendField($field, $value) : void
                                                                                                                                                              + Append the given text to the given element. + Can also add a selection to a select box.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->appendField('#mySelectbox', 'SelectValue');
                                                                                                                                                            +$I->appendField('#myTextField', 'appended');
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              attachFile($field, $filename) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              cancelPopup() : void
                                                                                                                                                              + Dismisses the active JavaScript popup, as created by window.alert, window.confirm, or window.prompt.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              checkOption($option) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              clearField($field) : void
                                                                                                                                                              + Clears given field which isn't empty.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->clearField('#username');
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              click($link, [$context]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              clickWithLeftButton([$cssOrXPath], [$offsetX], [$offsetY]) : void
                                                                                                                                                              + Performs click with the left mouse button on an element. + If the first parameter null then the offset is relative to the actual mouse position. + If the second and third parameters are given, + then the mouse is moved to an offset of the element's top-left corner. + Otherwise, the mouse is moved to the center of the element.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->clickWithLeftButton(['css' => '.checkout']);
                                                                                                                                                            +$I->clickWithLeftButton(null, 20, 50);
                                                                                                                                                            +$I->clickWithLeftButton(['css' => '.checkout'], 20, 50);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • clickWithRightButton([$cssOrXPath], [$offsetX], [$offsetY]) : void
                                                                                                                                                              + Performs contextual click with the right mouse button on an element. + If the first parameter null then the offset is relative to the actual mouse position. + If the second and third parameters are given, + then the mouse is moved to an offset of the element's top-left corner. + Otherwise, the mouse is moved to the center of the element.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->clickWithRightButton(['css' => '.checkout']);
                                                                                                                                                            +$I->clickWithRightButton(null, 20, 50);
                                                                                                                                                            +$I->clickWithRightButton(['css' => '.checkout'], 20, 50);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • closeTab() : void
                                                                                                                                                              + Closes current browser tab and switches to previous active tab.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->closeTab();
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • deactivatePlugin($pluginSlug) : void
                                                                                                                                                              + In the plugin administration screen deactivate a plugin clicking the "Deactivate" link.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugins administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              debugWebDriverLogs([?Codeception\TestInterface $test]) : void
                                                                                                                                                              + Print out latest Selenium Logs in debug mode

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              deleteSessionSnapshot($name) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSee($text, [$selector]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCheckboxIsChecked($checkbox) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCurrentUrlEquals($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeCurrentUrlMatches($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeElement($selector, [$attributes]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeElementInDOM($selector, [$attributes]) : void
                                                                                                                                                              + Opposite of seeElementInDOM.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInCurrentUrl($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInField($field, $value) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInFormFields($formSelector, array $params) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInPageSource($text) : void
                                                                                                                                                              + Checks that the page source doesn't contain the given string.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInPopup($text) : void
                                                                                                                                                              + Checks that the active JavaScript popup, + as created by window.alert|window.confirm|window.prompt, does NOT contain the given string.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInSource($raw) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeInTitle($title) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeLink($text, [$url]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeeOptionIsSelected($selector, $optionText) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dontSeePluginInstalled($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is not installed in the plugins administration screen.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              doubleClick($cssOrXPath) : void
                                                                                                                                                              + Performs a double-click on an element matched by CSS or XPath.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              dragAndDrop($source, $target) : void
                                                                                                                                                              + Performs a simple mouse drag-and-drop operation.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->dragAndDrop('#drag', '#drop');
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • executeAsyncJS($script, [array $arguments]) : void
                                                                                                                                                              + Executes asynchronous JavaScript. + A callback should be executed by JavaScript to exit from a script. + Callback is passed as a last element in arguments array. + Additional arguments can be passed as array in second parameter.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            // wait for 1200 milliseconds my running `setTimeout`
                                                                                                                                                            +* $I->executeAsyncJS('setTimeout(arguments[0], 1200)');
                                                                                                                                                            +
                                                                                                                                                            +$seconds = 1200; // or seconds are passed as argument
                                                                                                                                                            +$I->executeAsyncJS('setTimeout(arguments[1], arguments[0])', [$seconds]);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • executeInSelenium(Closure $function) : void
                                                                                                                                                              + Low-level API method. + If Codeception commands are not enough, this allows you to use Selenium WebDriver methods directly:
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            $I->executeInSelenium(function(\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
                                                                                                                                                            +  $webdriver->get('http://google.com');
                                                                                                                                                            +});
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This runs in the context of the + RemoteWebDriver class. + Try not to use this command on a regular basis. + If Codeception lacks a feature you need, please implement it and submit a patch.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • executeJS($script, [array $arguments]) : void
                                                                                                                                                              + Executes custom JavaScript.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            This example uses jQuery to get a value and assigns that value to a PHP variable:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$myVar = $I->executeJS('return $("#myField").val()');
                                                                                                                                                            +
                                                                                                                                                            +// additional arguments can be passed as array
                                                                                                                                                            +// Example shows `Hello World` alert:
                                                                                                                                                            +$I->executeJS("window.alert(arguments[0])", ['Hello world']);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              fillField($field, $value) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabActiveTheme() : void
                                                                                                                                                              + Returns the slug of the currently active themes.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              grabAttributeFrom($cssOrXpath, $attribute) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabAvailableThemes([$classes]) : void
                                                                                                                                                              + Returns the list of available themes.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              grabCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabCookiesWithPattern($cookiePattern) : void
                                                                                                                                                              + Returns all the cookies whose name matches a regex pattern.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabFromCurrentUrl([$uri]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabFullUrl() : void
                                                                                                                                                              + Grabs the current page full URL including the query vars.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabMultiple($cssOrXpath, [$attribute]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabPageSource() : void
                                                                                                                                                              + Grabs current page source code.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabTextFrom($cssOrXPathOrRegex) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabValueFrom($field) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              grabWordPressTestCookie([$name]) : void
                                                                                                                                                              + Returns WordPress default test cookie object if present.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              loadSessionSnapshot($name) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              logOut([$redirectTo]) : void
                                                                                                                                                              + Navigate to the default WordPress logout page and click the logout link.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              loginAs($username, $password, [$timeout], [$maxAttempts]) : void
                                                                                                                                                              + Login as the specified user.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not follow redirection, after the login, to any page. + Depending on the driven browser the login might be "too fast" and the server might have not + replied with valid cookies yet; in that case the method will re-attempt the login to obtain + the cookies.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • loginAsAdmin([$timeout], [$maxAttempts]) : void
                                                                                                                                                              + Login as the administrator user using the credentials specified in the module configuration.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not follow redirection, after the login, to any page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • makeElementScreenshot($selector, [$name]) : void
                                                                                                                                                              + Takes a screenshot of an element of the current window and saves it to tests/_output/debug.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->amOnPage('/user/edit');
                                                                                                                                                            +$I->makeElementScreenshot('#dialog', 'edit_page');
                                                                                                                                                            +// saved to: tests/_output/debug/edit_page.png
                                                                                                                                                            +$I->makeElementScreenshot('#dialog');
                                                                                                                                                            +// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              makeHtmlSnapshot([$name]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              makeScreenshot([$name]) : void
                                                                                                                                                              + Takes a screenshot of the current window and saves it to tests/_output/debug.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->amOnPage('/user/edit');
                                                                                                                                                            +$I->makeScreenshot('edit_page');
                                                                                                                                                            +// saved to: tests/_output/debug/edit_page.png
                                                                                                                                                            +$I->makeScreenshot();
                                                                                                                                                            +// saved to: tests/_output/debug/2017-05-26_14-24-11_4b3403665fea6.png
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              maximizeWindow() : void
                                                                                                                                                              + Maximizes the current window.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              moveBack() : void
                                                                                                                                                              + Moves back in history.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              moveForward() : void
                                                                                                                                                              + Moves forward in history.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              moveMouseOver([$cssOrXPath], [$offsetX], [$offsetY]) : void
                                                                                                                                                              + Move mouse over the first element matched by the given locator. + If the first parameter null then the page is used. + If the second and third parameters are given, + then the mouse is moved to an offset of the element's top-left corner. + Otherwise, the mouse is moved to the center of the element.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->moveMouseOver(['css' => '.checkout']);
                                                                                                                                                            +$I->moveMouseOver(null, 20, 50);
                                                                                                                                                            +$I->moveMouseOver(['css' => '.checkout'], 20, 50);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • openNewTab() : void
                                                                                                                                                              + Opens a new browser tab and switches to it.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            <?php
                                                                                                                                                            +$I->openNewTab();
                                                                                                                                                            +
                                                                                                                                                            + The tab is opened with JavaScript's window.open(), which means: + * Some adblockers might restrict it. + * The sessionStorage is copied to the new tab (contrary to a tab that was manually opened by the user)

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • performOn($element, $actions, [$timeout]) : void
                                                                                                                                                              + Waits for element and runs a sequence of actions inside its context. + Actions can be defined with array, callback, or Codeception\Util\ActionSequence instance.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Actions as array are recommended for simple to combine "waitForElement" with assertions; + waitForElement($el) and see('text', $el) can be simplified to:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->performOn($el, ['see' => 'text']);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            List of actions can be pragmatically build using Codeception\Util\ActionSequence:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->performOn('.model', ActionSequence::build()
                                                                                                                                                            +    ->see('Warning')
                                                                                                                                                            +    ->see('Are you sure you want to delete this?')
                                                                                                                                                            +    ->click('Yes')
                                                                                                                                                            +);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Actions executed from array or ActionSequence will print debug output for actions, and adds an action name to + exception on failure.

                                                                                                                                                            +

                                                                                                                                                            Whenever you need to define more actions a callback can be used. A WebDriver module is passed for argument:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->performOn('.rememberMe', function (WebDriver $I) {
                                                                                                                                                            +     $I->see('Remember me next time');
                                                                                                                                                            +     $I->seeElement('#LoginForm_rememberMe');
                                                                                                                                                            +     $I->dontSee('Login');
                                                                                                                                                            +});
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            In 3rd argument you can set number a seconds to wait for element to appear

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • pressKey($element, $char) : void
                                                                                                                                                              + Presses the given key on the given element. + To specify a character and modifier (e.g. Ctrl, Alt, Shift, Meta), pass an array for $char with + the modifier as the first element and the character as the second. + For special keys, use the constants from Facebook\WebDriver\WebDriverKeys.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// <input id="page" value="old" />
                                                                                                                                                            +$I->pressKey('#page','a'); // => olda
                                                                                                                                                            +$I->pressKey('#page',array('ctrl','a'),'new'); //=> new
                                                                                                                                                            +$I->pressKey('#page',array('shift','111'),'1','x'); //=> old!!!1x
                                                                                                                                                            +$I->pressKey('descendant-or-self::*[@id='page']','u'); //=> oldu
                                                                                                                                                            +$I->pressKey('#name', array('ctrl', 'a'), \Facebook\WebDriver\WebDriverKeys::DELETE); //=>''
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              reloadPage() : void
                                                                                                                                                              + Reloads the current page.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              resetCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              resizeWindow($width, $height) : void
                                                                                                                                                              + Resize the current window.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->resizeWindow(800, 600);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              saveSessionSnapshot($name) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              scrollTo($selector, [$offsetX], [$offsetY]) : void
                                                                                                                                                              + Move to the middle of the given element matched by the given locator. + Extra shift, calculated from the top-left corner of the element, + can be set by passing $offsetX and $offsetY parameters.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->scrollTo(['css' => '.checkout'], 20, 50);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              see($text, [$selector]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCheckboxIsChecked($checkbox) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCookie($cookie, [array $params]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCurrentUrlEquals($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeCurrentUrlMatches($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeElement($selector, [$attributes]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeElementInDOM($selector, [$attributes]) : void
                                                                                                                                                              + Checks that the given element exists on the page, even it is invisible.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->seeElementInDOM('//form/input[type=hidden]');
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seeErrorMessage([$classes]) : void
                                                                                                                                                              + In an administration screen look for an error admin notice.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The check is class-based to decouple from internationalization. + The method will not handle authentication and navigation the administration area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              seeInCurrentUrl($uri) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInField($field, $value) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInFormFields($formSelector, array $params) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInPageSource($text) : void
                                                                                                                                                              + Checks that the page source contains the given string.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->seeInPageSource('<link rel="apple-touch-icon"');
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              seeInPopup($text) : void
                                                                                                                                                              + Checks that the active JavaScript popup, + as created by window.alert|window.confirm|window.prompt, contains the given string.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInSource($raw) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeInTitle($title) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeLink($text, [$url]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeMessage([$classes]) : void
                                                                                                                                                              + In an administration screen look for an admin notice.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The check is class-based to decouple from internationalization. + The method will not handle authentication and navigation the administration area.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              seeNumberOfElements($selector, $expected) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeNumberOfElementsInDOM($selector, $expected) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seeNumberOfTabs($number) : void
                                                                                                                                                              + Checks current number of opened tabs

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->seeNumberOfTabs(2);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              seeOptionIsSelected($selector, $optionText) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              seePluginActivated($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is activated in the plugin administration screen.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seePluginDeactivated($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is not activated in the plugins administration screen.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seePluginInstalled($pluginSlug) : void
                                                                                                                                                              + Assert a plugin is installed, no matter its activation status, in the plugin administration screen.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seeThemeActivated($slug) : void
                                                                                                                                                              + Verifies that a theme is active.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will not handle authentication and navigation to the themes administration page.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • seeWpDiePage() : void
                                                                                                                                                              + Checks that the current page is one generated by the wp_die function.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The method will try to identify the page based on the default WordPress die page HTML attributes.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              selectOption($select, $option) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              setCookie($cookie, $value, [array $params], [$showDebug]) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              submitForm($selector, array $params, [$button]) : void
                                                                                                                                                              + Submits the given form on the page, optionally with the given form + values. Give the form fields values as an array. Note that hidden fields + can't be accessed.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Skipped fields will be filled by their values from the page. + You don't need to click the 'Submit' button afterwards. + This command itself triggers the request to form's action.

                                                                                                                                                            +

                                                                                                                                                            You can optionally specify what button's value to include + in the request with the last parameter as an alternative to + explicitly setting its value in the second parameter, as + button values are not otherwise included in the request.

                                                                                                                                                            +

                                                                                                                                                            Examples:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->submitForm('#login', [
                                                                                                                                                            +    'login' => 'davert',
                                                                                                                                                            +    'password' => '123456'
                                                                                                                                                            +]);
                                                                                                                                                            +// or
                                                                                                                                                            +$I->submitForm('#login', [
                                                                                                                                                            +    'login' => 'davert',
                                                                                                                                                            +    'password' => '123456'
                                                                                                                                                            +], 'submitButtonName');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            For example, given this sample "Sign Up" form:

                                                                                                                                                            +
                                                                                                                                                            <form action="/sign_up">
                                                                                                                                                            +    Login:
                                                                                                                                                            +    <input type="text" name="user[login]" /><br/>
                                                                                                                                                            +    Password:
                                                                                                                                                            +    <input type="password" name="user[password]" /><br/>
                                                                                                                                                            +    Do you agree to our terms?
                                                                                                                                                            +    <input type="checkbox" name="user[agree]" /><br/>
                                                                                                                                                            +    Select pricing plan:
                                                                                                                                                            +    <select name="plan">
                                                                                                                                                            +        <option value="1">Free</option>
                                                                                                                                                            +        <option value="2" selected="selected">Paid</option>
                                                                                                                                                            +    </select>
                                                                                                                                                            +    <input type="submit" name="submitButton" value="Submit" />
                                                                                                                                                            +</form>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You could write the following to submit it:

                                                                                                                                                            +

                                                                                                                                                            <?php
                                                                                                                                                            +$I->submitForm(
                                                                                                                                                            +    '#userForm',
                                                                                                                                                            +    [
                                                                                                                                                            +        'user[login]' => 'Davert',
                                                                                                                                                            +        'user[password]' => '123456',
                                                                                                                                                            +        'user[agree]' => true
                                                                                                                                                            +    ],
                                                                                                                                                            +    'submitButton'
                                                                                                                                                            +);
                                                                                                                                                            +
                                                                                                                                                            + Note that "2" will be the submitted value for the "plan" field, as it is + the selected option.

                                                                                                                                                            +

                                                                                                                                                            Also note that this differs from PhpBrowser, in that + 'user' => [ 'login' => 'Davert' ] is not supported at the moment. + Named array keys must be included in the name as above.

                                                                                                                                                            +

                                                                                                                                                            Pair this with seeInFormFields for quick testing magic.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$form = [
                                                                                                                                                            +     'field1' => 'value',
                                                                                                                                                            +     'field2' => 'another value',
                                                                                                                                                            +     'checkbox1' => true,
                                                                                                                                                            +     // ...
                                                                                                                                                            +];
                                                                                                                                                            +$I->submitForm('//form[@id=my-form]', $form, 'submitButton');
                                                                                                                                                            +// $I->amOnPage('/path/to/form-page') may be needed
                                                                                                                                                            +$I->seeInFormFields('//form[@id=my-form]', $form);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameter values must be set to arrays for multiple input fields + of the same name, or multi-select combo boxes. For checkboxes, + either the string value can be used, or boolean values which will + be replaced by the checkbox's value in the DOM.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->submitForm('#my-form', [
                                                                                                                                                            +     'field1' => 'value',
                                                                                                                                                            +     'checkbox' => [
                                                                                                                                                            +         'value of first checkbox',
                                                                                                                                                            +         'value of second checkbox',
                                                                                                                                                            +     ],
                                                                                                                                                            +     'otherCheckboxes' => [
                                                                                                                                                            +         true,
                                                                                                                                                            +         false,
                                                                                                                                                            +         false,
                                                                                                                                                            +     ],
                                                                                                                                                            +     'multiselect' => [
                                                                                                                                                            +         'first option value',
                                                                                                                                                            +         'second option value',
                                                                                                                                                            +     ]
                                                                                                                                                            +]);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Mixing string and boolean values for a checkbox's value is not supported + and may produce unexpected results.

                                                                                                                                                            +

                                                                                                                                                            Field names ending in "[]" must be passed without the trailing square + bracket characters, and must contain an array for its value. This allows + submitting multiple values with the same name, consider:

                                                                                                                                                            +
                                                                                                                                                            $I->submitForm('#my-form', [
                                                                                                                                                            +    'field[]' => 'value',
                                                                                                                                                            +    'field[]' => 'another value', // 'field[]' is already a defined key
                                                                                                                                                            +]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The solution is to pass an array value:

                                                                                                                                                            +
                                                                                                                                                            // this way both values are submitted
                                                                                                                                                            +$I->submitForm('#my-form', [
                                                                                                                                                            +    'field' => [
                                                                                                                                                            +        'value',
                                                                                                                                                            +        'another value',
                                                                                                                                                            +    ]
                                                                                                                                                            +]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The $button parameter can be either a string, an array or an instance + of Facebook\WebDriver\WebDriverBy. When it is a string, the + button will be found by its "name" attribute. If $button is an + array then it will be treated as a strict selector and a WebDriverBy + will be used verbatim.

                                                                                                                                                            +

                                                                                                                                                            For example, given the following HTML:

                                                                                                                                                            +
                                                                                                                                                            <input type="submit" name="submitButton" value="Submit" />
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            $button could be any one of the following: + - 'submitButton' + - ['name' => 'submitButton'] + - WebDriverBy::name('submitButton')

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • switchToFrame([$locator]) : void
                                                                                                                                                              + Switch to another frame on the page.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example: +

                                                                                                                                                            <frame name="another_frame" id="fr1" src="http://example.com">
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +# switch to frame by name
                                                                                                                                                            +$I->switchToFrame("another_frame");
                                                                                                                                                            +# switch to frame by CSS or XPath
                                                                                                                                                            +$I->switchToFrame("#fr1");
                                                                                                                                                            +# switch to parent page
                                                                                                                                                            +$I->switchToFrame();
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • switchToIFrame([$locator]) : void
                                                                                                                                                              + Switch to another iframe on the page.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example: +

                                                                                                                                                            <iframe name="another_frame" id="fr1" src="http://example.com">
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +# switch to iframe by name
                                                                                                                                                            +$I->switchToIFrame("another_frame");
                                                                                                                                                            +# switch to iframe by CSS or XPath
                                                                                                                                                            +$I->switchToIFrame("#fr1");
                                                                                                                                                            +# switch to parent page
                                                                                                                                                            +$I->switchToIFrame();
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • switchToNextTab([$offset]) : void
                                                                                                                                                              + Switches to next browser tab. + An offset can be specified.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// switch to next tab
                                                                                                                                                            +$I->switchToNextTab();
                                                                                                                                                            +// switch to 2nd next tab
                                                                                                                                                            +$I->switchToNextTab(2);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • switchToPreviousTab([$offset]) : void
                                                                                                                                                              + Switches to previous browser tab. + An offset can be specified.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// switch to previous tab
                                                                                                                                                            +$I->switchToPreviousTab();
                                                                                                                                                            +// switch to 2nd previous tab
                                                                                                                                                            +$I->switchToPreviousTab(2);
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • switchToWindow([$name]) : void
                                                                                                                                                              + Switch to another window identified by name.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            The window can only be identified by name. If the $name parameter is blank, the parent window will be used.

                                                                                                                                                            +

                                                                                                                                                            Example: +

                                                                                                                                                            <input type="button" value="Open window" onclick="window.open('http://example.com', 'another_window')">
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->click("Open window");
                                                                                                                                                            +# switch to another window
                                                                                                                                                            +$I->switchToWindow("another_window");
                                                                                                                                                            +# switch to parent window
                                                                                                                                                            +$I->switchToWindow();
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If the window has no name, match it by switching to next active tab using switchToNextTab method.

                                                                                                                                                            +

                                                                                                                                                            Or use native Selenium functions to get access to all opened windows:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
                                                                                                                                                            +     $handles=$webdriver->getWindowHandles();
                                                                                                                                                            +     $last_window = end($handles);
                                                                                                                                                            +     $webdriver->switchTo()->window($last_window);
                                                                                                                                                            +});
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • type($text, [$delay]) : void
                                                                                                                                                              + Type in characters on active element. + With a second parameter you can specify delay between key presses.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +// activate input element
                                                                                                                                                            +$I->click('#input');
                                                                                                                                                            +
                                                                                                                                                            +// type text in active element
                                                                                                                                                            +$I->type('Hello world');
                                                                                                                                                            +
                                                                                                                                                            +// type text with a 1sec delay between chars
                                                                                                                                                            +$I->type('Hello World', 1);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This might be useful when you an input reacts to typing and you need to slow it down to emulate human behavior. + For instance, this is how Credit Card fields can be filled in.

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              typeInPopup($keys) : void
                                                                                                                                                              + Enters text into a native JavaScript prompt popup, as created by window.prompt.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              uncheckOption($option) : void

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              unselectOption($select, $option) : void
                                                                                                                                                              + Unselect an option in the given select box.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              wait($timeout) : void
                                                                                                                                                              + Wait for $timeout seconds.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              waitForElement($element, [$timeout]) : void
                                                                                                                                                              + Waits up to $timeout seconds for an element to appear on the page. + If the element doesn't appear, a timeout exception is thrown.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->waitForElement('#agree_button', 30); // secs
                                                                                                                                                            +$I->click('#agree_button');
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • waitForElementChange($element, Closure $callback, [$timeout]) : void
                                                                                                                                                              + Waits up to $timeout seconds for the given element to change. + Element "change" is determined by a callback function which is called repeatedly + until the return value evaluates to true.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +use \Facebook\WebDriver\WebDriverElement
                                                                                                                                                            +$I->waitForElementChange('#menu', function(WebDriverElement $el) {
                                                                                                                                                            +    return $el->isDisplayed();
                                                                                                                                                            +}, 100);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • waitForElementClickable($element, [$timeout]) : void
                                                                                                                                                              + Waits up to $timeout seconds for the given element to be clickable. + If element doesn't become clickable, a timeout exception is thrown.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->waitForElementClickable('#agree_button', 30); // secs
                                                                                                                                                            +$I->click('#agree_button');
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • waitForElementNotVisible($element, [$timeout]) : void
                                                                                                                                                              + Waits up to $timeout seconds for the given element to become invisible. + If element stays visible, a timeout exception is thrown.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->waitForElementNotVisible('#agree_button', 30); // secs
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • waitForElementVisible($element, [$timeout]) : void
                                                                                                                                                              + Waits up to $timeout seconds for the given element to be visible on the page. + If element doesn't appear, a timeout exception is thrown.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->waitForElementVisible('#agree_button', 30); // secs
                                                                                                                                                            +$I->click('#agree_button');
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • waitForJS($script, [$timeout]) : void
                                                                                                                                                              + Executes JavaScript and waits up to $timeout seconds for it to return true.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            In this example we will wait up to 60 seconds for all jQuery AJAX requests to finish.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->waitForJS("return $.active == 0;", 60);
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • +

                                                                                                                                                              waitForJqueryAjax([$time]) : void
                                                                                                                                                              + Waits for any jQuery triggered AJAX request to be resolved.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • +

                                                                                                                                                              waitForText($text, [$timeout], [$selector]) : void
                                                                                                                                                              + Waits up to $timeout seconds for the given string to appear on the page.

                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Can also be passed a selector to search in, be as specific as possible when using selectors. + waitForText() will only watch the first instance of the matching selector / text provided. + If the given text doesn't appear, a timeout exception is thrown.

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +$I->waitForText('foo', 30); // secs
                                                                                                                                                            +$I->waitForText('foo', 30, '.title'); // secs
                                                                                                                                                            +?>
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This class extends \Codeception\Module\WebDriver

                                                                                                                                                            +

                                                                                                                                                            This class implements \Codeception\Lib\Interfaces\RequiresPackage, \Codeception\Lib\Interfaces\ConflictsWithModule, \Codeception\Lib\Interfaces\ElementLocator, \Codeception\Lib\Interfaces\PageSourceSaver, \Codeception\Lib\Interfaces\ScreenshotSaver, \Codeception\Lib\Interfaces\SessionSnapshot, \Codeception\Lib\Interfaces\MultiSession, \Codeception\Lib\Interfaces\Remote, \Codeception\Lib\Interfaces\Web

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/modules/WordPress/index.html b/v3/modules/WordPress/index.html new file mode 100644 index 000000000..215e997fa --- /dev/null +++ b/v3/modules/WordPress/index.html @@ -0,0 +1,3308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + WordPress - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            WordPress module

                                                                                                                                                            +

                                                                                                                                                            This module requires good knowledge and attention to be used effectively; you can replace it with a combination of the WPBrowser module together with the WPLoader module in loadOnly mode. +This module should be used in functional tests, see levels of testing for more information.
                                                                                                                                                            +This module provides a middle-ground, in terms of testing and effects, between the fully isolated approach of the WPBrowser module and the fully integrated approach of the WPLoader module with loadOnly set to false.
                                                                                                                                                            +It allows to interact with WordPress on a very high level, using methods like $I->loginAs() or $I->amOnPage() as you could do with the WPBrowser module while also loading WordPress in the same variable scope as the tests as the WPLoader module would. +Due to WordPress reliance on constants, globals and side-effects this module will make requests to WordPress in an insulated manner and reproduce WordPress environment (globals and super-globals) after each response in the tests variable scope. +The module simulates a user interaction with the site without Javascript support, use the WPWebDriver module for any kind of testing that requires Javascript-based interaction with the site.

                                                                                                                                                            +

                                                                                                                                                            Module requirements for Codeception 4.0+

                                                                                                                                                            +

                                                                                                                                                            This module requires the codeception/lib-innerbrowser Composer package to work when wp-browser is used with Codeception 4.0.

                                                                                                                                                            +

                                                                                                                                                            To install the package run:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev codeception/lib-innerbrowser:^1.0
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Detecting requests coming from this module

                                                                                                                                                            +

                                                                                                                                                            When it runs this module will set the WPBROWSER_HOST_REQUEST environment variable.
                                                                                                                                                            +You can detect and use that information to, as an example, use the correct database in your test site wp-config.php file: +

                                                                                                                                                            <?php
                                                                                                                                                            +if ( 
                                                                                                                                                            +    // Custom header.
                                                                                                                                                            +    isset( $_SERVER['HTTP_X_TESTING'] )
                                                                                                                                                            +    // Custom user agent.
                                                                                                                                                            +    || ( isset( $_SERVER['HTTP_USER_AGENT'] ) && $_SERVER['HTTP_USER_AGENT'] === 'wp-browser' )
                                                                                                                                                            +    // The env var set by the WPClIr or WordPress modules.
                                                                                                                                                            +    || getenv( 'WPBROWSER_HOST_REQUEST' )
                                                                                                                                                            +) {
                                                                                                                                                            +    // Use the test database if the request comes from a test.
                                                                                                                                                            +    define( 'DB_NAME', 'wordpress_test' );
                                                                                                                                                            +} else {
                                                                                                                                                            +    // Else use the default one.
                                                                                                                                                            +    define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            +}
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Configuration

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • wpRootFolder required The absolute, or relative to the project root folder, path to the root WordPress installation folder. The WordPress installation root folder is the one that contains the wp-load.php file.
                                                                                                                                                            • +
                                                                                                                                                            • adminUsername required - This is the login name, not the "nice" name, of the administrator user of the WordPress test site. This will be used to fill the username field in WordPress login page.
                                                                                                                                                            • +
                                                                                                                                                            • adminPassword required - This is the the password of the administrator use of the WordPress test site. This will be used to fill the password in WordPress login page.
                                                                                                                                                            • +
                                                                                                                                                            • adminPath required - The path, relative to the WordPress test site home URL, to the administration area, usually /wp-admin.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Example configuration

                                                                                                                                                            +
                                                                                                                                                              modules:
                                                                                                                                                            +      enabled:
                                                                                                                                                            +          - WordPress
                                                                                                                                                            +      config:
                                                                                                                                                            +          WordPress:
                                                                                                                                                            +              wpRootFolder: "/var/www/wordpress"
                                                                                                                                                            +              adminUsername: 'admin'
                                                                                                                                                            +              adminPassword: 'password'
                                                                                                                                                            +              adminPath: '/wp-admin'
                                                                                                                                                            +
                                                                                                                                                            + + +

                                                                                                                                                            Public API

                                                                                                                                                            + + +

                                                                                                                                                            amEditingPostWithId

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Go to the admin page to edit the post with the specified ID. The method will not handle authentication the admin area.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $postId = $I->havePostInDatabase();
                                                                                                                                                            +  $I->amEditingPostWithId($postId);
                                                                                                                                                            +  $I->fillField('post_title', 'Post title');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • int $id - The post ID.
                                                                                                                                                            + +

                                                                                                                                                            amOnAdminAjaxPage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Go to the admin-ajax.php page to start a synchronous, and blocking, GET AJAX request. The method will not handle authentication, nonces or authorization.

                                                                                                                                                            +
                                                                                                                                                            $I->amOnAdminAjaxPage(['action' => 'my-action', 'data' => ['id' => 23], 'nonce' => $nonce]);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/\Codeception\Module\array $queryVars - A string or array of query variables to append to the AJAX path.
                                                                                                                                                            + +

                                                                                                                                                            amOnAdminPage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Go to a page in the admininstration area of the site.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAs('user', 'password');
                                                                                                                                                            +  // Go to the plugins management screen.
                                                                                                                                                            +  $I->amOnAdminPage('/plugins.php');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $page - The path, relative to the admin area URL, to the page.
                                                                                                                                                            + +

                                                                                                                                                            amOnCronPage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Go to the cron page to start a synchronous, and blocking, GET request to the cron script.

                                                                                                                                                            +
                                                                                                                                                            // Triggers the cron job with an optional query argument.
                                                                                                                                                            +  $I->amOnCronPage('/?some-query-var=some-value');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/\Codeception\Module\array $queryVars - A string or array of query variables to append to the AJAX path.
                                                                                                                                                            + +

                                                                                                                                                            amOnPage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Go to a page on the site. The module will try to reach the page, relative to the URL specified in the module configuration, without applying any permalink resolution.

                                                                                                                                                            +
                                                                                                                                                            // Go the the homepage.
                                                                                                                                                            +  $I->amOnPage('/');
                                                                                                                                                            +  // Go to the single page of post with ID 23.
                                                                                                                                                            +  $I->amOnPage('/?p=23');
                                                                                                                                                            +  // Go to search page for the string "foo".
                                                                                                                                                            +  $I->amOnPage('/?s=foo');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $page - The path to the page, relative to the the root URL.
                                                                                                                                                            + +

                                                                                                                                                            amOnPagesPage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Go the "Pages" administration screen. The method will not handle authentication.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $I->amOnPagesPage();
                                                                                                                                                            +  $I->see('Add New');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            amOnPluginsPage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Go to the plugins administration screen. The method will not handle authentication.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $I->amOnPluginsPage();
                                                                                                                                                            +  $I->activatePlugin('hello-dolly');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            dontSeePluginInstalled

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Assert a plugin is not installed in the plugins administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $I->amOnPluginsPage();
                                                                                                                                                            +  $I->dontSeePluginInstalled('my-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $pluginSlug - The plugin slug, like "hello-dolly".
                                                                                                                                                            + +

                                                                                                                                                            extractCookie

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Grab a cookie value from the current session, sets it in the $_COOKIE array and returns its value. This method utility is to get, in the scope of test code, the value of a cookie set during the tests.

                                                                                                                                                            +
                                                                                                                                                            $id = $I->haveUserInDatabase('user', 'subscriber', ['user_pass' => 'pass']);
                                                                                                                                                            +  $I->loginAs('user', 'pass');
                                                                                                                                                            +  // The cookie is now set in the `$_COOKIE` super-global.
                                                                                                                                                            +  $I->extractCookie(LOGGED_IN_COOKIE);
                                                                                                                                                            +  // Generate a nonce using WordPress methods (see WPLoader in loadOnly mode) with correctly set context.
                                                                                                                                                            +  wp_set_current_user($id);
                                                                                                                                                            +  $nonce = wp_create_nonce('wp_rest');
                                                                                                                                                            +  // Use the generated nonce to make a request to the the REST API.
                                                                                                                                                            +  $I->haveHttpHeader('X-WP-Nonce', $nonce);
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $cookie - The cookie name.
                                                                                                                                                            • +
                                                                                                                                                            • array/\Codeception\Module\array/array $params - Parameters to filter the cookie value.
                                                                                                                                                            + +

                                                                                                                                                            getResponseContent

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns content of the last response. This method exposes an underlying API for custom assertions.

                                                                                                                                                            +
                                                                                                                                                            // In test class.
                                                                                                                                                            +  $this->assertContains($text, $this->getResponseContent(), "foo-bar");
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            getWpRootFolder

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns the absolute path to the WordPress root folder.

                                                                                                                                                            +
                                                                                                                                                            $root = $I->getWpRootFolder();
                                                                                                                                                            +  $this->assertFileExists($root . '/someFile.txt');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            grabWordPressTestCookie

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Returns WordPress default test cookie object if present.

                                                                                                                                                            +
                                                                                                                                                            // Grab the default WordPress test cookie.
                                                                                                                                                            +  $wpTestCookie = $I->grabWordPressTestCookie();
                                                                                                                                                            +  // Grab a customized version of the test cookie.
                                                                                                                                                            +  $myTestCookie = $I->grabWordPressTestCookie('my_test_cookie');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $name - Optional, overrides the default cookie name.
                                                                                                                                                            + +

                                                                                                                                                            logOut

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Navigate to the default WordPress logout page and click the logout link.

                                                                                                                                                            +
                                                                                                                                                            // Log out using the `wp-login.php` form and return to the current page.
                                                                                                                                                            +  $I->logOut(true);
                                                                                                                                                            +  // Log out using the `wp-login.php` form and remain there.
                                                                                                                                                            +  $I->logOut(false);
                                                                                                                                                            +  // Log out using the `wp-login.php` form and move to another page.
                                                                                                                                                            +  $I->logOut('/some-other-page');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • bool/bool/string $redirectTo - Whether to redirect to another (optionally specified) page after the logout.
                                                                                                                                                            + +

                                                                                                                                                            loginAs

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Login as the specified user. The method will not follow redirection, after the login, to any page.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAs('user', 'password');
                                                                                                                                                            +  $I->amOnAdminPage('/');
                                                                                                                                                            +  $I->seeElement('.admin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $username - The user login name.
                                                                                                                                                            • +
                                                                                                                                                            • string $password - The user password in plain text.
                                                                                                                                                            + +

                                                                                                                                                            loginAsAdmin

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Login as the administrator user using the credentials specified in the module configuration. The method will not follow redirection, after the login, to any page.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $I->amOnAdminPage('/');
                                                                                                                                                            +  $I->see('Dashboard');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            seeErrorMessage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            In an administration screen look for an error admin notice. The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area. .notice.notice-error ones.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin()
                                                                                                                                                            +  $I->amOnAdminPage('/');
                                                                                                                                                            +  $I->seeErrorMessage('.my-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/string/\Codeception\Module\array $classes - A list of classes the notice should have other than the
                                                                                                                                                            + +

                                                                                                                                                            seeMessage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            In an administration screen look for an admin notice. The check is class-based to decouple from internationalization. The method will not handle authentication and navigation the administration area.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin()
                                                                                                                                                            +  $I->amOnAdminPage('/');
                                                                                                                                                            +  $I->seeMessage('.missing-api-token.my-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string/\Codeception\Module\array/string $classes - A list of classes the message should have in addition to the .notice one.
                                                                                                                                                            + +

                                                                                                                                                            seePluginActivated

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Assert a plugin is activated in the plugin administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $I->amOnPluginsPage();
                                                                                                                                                            +  $I->seePluginActivated('my-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $pluginSlug - The plugin slug, like "hello-dolly".
                                                                                                                                                            + +

                                                                                                                                                            seePluginDeactivated

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Assert a plugin is not activated in the plugins administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $I->amOnPluginsPage();
                                                                                                                                                            +  $I->seePluginDeactivated('my-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $pluginSlug - The plugin slug, like "hello-dolly".
                                                                                                                                                            + +

                                                                                                                                                            seePluginInstalled

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Assert a plugin is installed, no matter its activation status, in the plugin administration screen. The method will not handle authentication and navigation to the plugin administration screen.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAsAdmin();
                                                                                                                                                            +  $I->amOnPluginsPage();
                                                                                                                                                            +  $I->seePluginInstalled('my-plugin');
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Parameters

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • string $pluginSlug - The plugin slug, like "hello-dolly".
                                                                                                                                                            + +

                                                                                                                                                            seeWpDiePage

                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Checks that the current page is one generated by the wp_die function. The method will try to identify the page based on the default WordPress die page HTML attributes.

                                                                                                                                                            +
                                                                                                                                                            $I->loginAs('user', 'password');
                                                                                                                                                            +  $I->amOnAdminPage('/forbidden');
                                                                                                                                                            +  $I->seeWpDiePage();
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This class extends \Codeception\Lib\Framework

                                                                                                                                                            +

                                                                                                                                                            This class implements \Codeception\Lib\Interfaces\Web, \Codeception\Lib\Interfaces\PageSourceSaver, \Codeception\Lib\Interfaces\ElementLocator, \Codeception\Lib\Interfaces\ConflictsWithModule, \Codeception\Lib\Interfaces\DependsOnModule

                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/requirements/index.html b/v3/requirements/index.html new file mode 100644 index 000000000..e65f40b6d --- /dev/null +++ b/v3/requirements/index.html @@ -0,0 +1,3047 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Requirements - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Requirements

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Requirements

                                                                                                                                                            +

                                                                                                                                                            wp-browser has some requirements your development environment will need to fulfill for it to work correctly.

                                                                                                                                                            +

                                                                                                                                                            PHP

                                                                                                                                                            +

                                                                                                                                                            The minimum supported version of PHP supported by wp-browser is 5.6.

                                                                                                                                                            +

                                                                                                                                                            This requirement does not reflect on the minimum PHP version your plugin might require; see the FAQs for more information.

                                                                                                                                                            +

                                                                                                                                                            Composer

                                                                                                                                                            +

                                                                                                                                                            There is no phar version of wp-browser and it can only be installed using Composer.

                                                                                                                                                            +

                                                                                                                                                            See Composer installation guide for more information.

                                                                                                                                                            +

                                                                                                                                                            WordPress, MySQL, Apache/Nginx

                                                                                                                                                            +

                                                                                                                                                            wp-browser will not download, install and configure WordPress for you.

                                                                                                                                                            +

                                                                                                                                                            It will also not download, install and setup MySQL, Apache, Nginx or any other technology required by a fully functional WordPress installation for you.

                                                                                                                                                            +

                                                                                                                                                            You need to set up a local WordPress installation on your own; you can use your preferred solution to do it.

                                                                                                                                                            +

                                                                                                                                                            In the documentation I will show automated ways to do this but, for most projects, that's not the best solution.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/setting-up-minimum-wordpress-installation/index.html b/v3/setting-up-minimum-wordpress-installation/index.html new file mode 100644 index 000000000..e573a45d3 --- /dev/null +++ b/v3/setting-up-minimum-wordpress-installation/index.html @@ -0,0 +1,2990 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Setting up a minimum WordPress installation - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Setting up a minimum WordPress installation

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up a minimum WordPress installation

                                                                                                                                                            +

                                                                                                                                                            As mentioned in Installation section wp-browser will not download, configure and install WordPress for you.

                                                                                                                                                            +

                                                                                                                                                            On a high level, once WordPress is installed and configured, whatever local development environment solution you've used, there are some information you'll need to gather before moving into wp-browser configuration.

                                                                                                                                                            +

                                                                                                                                                            While there will be a section dedicated to different environments and setups I will outline below the example setup I will use, in the next section, to configure wp-browser:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • WordPress is installed, on my machine, at /Users/luca/Sites/wordpress.
                                                                                                                                                            • +
                                                                                                                                                            • I'm running MySQL server locally; I can connect to the MySQL server with the command mysql -u root -h 127.0.0.1 -P 3306; there is no password.
                                                                                                                                                            • +
                                                                                                                                                            • I've created two databases, wordpress and tests, with the command: +
                                                                                                                                                              mysql -u root -h 127.0.0.1 -P 3306 -e "create database if not exists wordpress; create database if not exists tests"
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • I've configured the /Users/luca/Sites/wordpress/wp-config.php file like below (redacted for brevity): +
                                                                                                                                                              <?php
                                                                                                                                                              +define( 'DB_NAME', 'wordpress' );
                                                                                                                                                              +define( 'DB_USER', 'root' );
                                                                                                                                                              +define( 'DB_PASSWORD', '' );
                                                                                                                                                              +define( 'DB_HOST', '127.0.0.1' );
                                                                                                                                                              +define( 'DB_CHARSET', 'utf8' );
                                                                                                                                                              +define( 'DB_COLLATE', '' );
                                                                                                                                                              +
                                                                                                                                                              +$table_prefix = 'wp_';
                                                                                                                                                              +
                                                                                                                                                              +if ( ! defined( 'ABSPATH' ) )
                                                                                                                                                              +    define( 'ABSPATH', dirname( __FILE__ ) . '/' );
                                                                                                                                                              +
                                                                                                                                                              +require_once ABSPATH . 'wp-settings.php';
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • To serve the site I'm using PHP built-in server with the command: +
                                                                                                                                                              (cd /Users/luca/Sites/wordpress; php -S localhost:8080)
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            • I can access the WordPress homepage at http://localhost:8080 and the administration area at http://localhost:8080/wp-admin.
                                                                                                                                                            • +
                                                                                                                                                            • I've installed WordPress via its UI (http://localhost:8080/wp-admin), the administrator username is admin, the administrator password is password.
                                                                                                                                                            • +
                                                                                                                                                            • I'm testing a plugin and that plugin is in the folder, relative to the WordPress root folder, wp-content/plugins/acme-plugin.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            With all the steps above done I can now move into the actual wp-browser configuration phase.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/tutorials/automatically-change-db-in-tests/index.html b/v3/tutorials/automatically-change-db-in-tests/index.html new file mode 100644 index 000000000..9f49310db --- /dev/null +++ b/v3/tutorials/automatically-change-db-in-tests/index.html @@ -0,0 +1,3045 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Automatically change database during acceptance and functional tests - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Automatically change database during acceptance and functional tests

                                                                                                                                                            +

                                                                                                                                                            You should always back up any site you run tests on if you care about the site content.

                                                                                                                                                            +

                                                                                                                                                            Now this disclaimer has been made ad nauseam; there's a simple way to use a different database when during tests.

                                                                                                                                                            +

                                                                                                                                                            Identifying requests

                                                                                                                                                            +

                                                                                                                                                            The first component of this solution is identifying the source of the current HTTP request.
                                                                                                                                                            +WordPress makes this identification before deciding which database to use.

                                                                                                                                                            +

                                                                                                                                                            To provide the WordPress installation with this information, you can set the headers entry of the WPBrowser or WPWebDriver module in the suite configuration file.

                                                                                                                                                            +

                                                                                                                                                            As an example here is an acceptance suite configuration file setting two custom headers, X_WPBROWSER_REQUEST and X_TEST_REQUEST, on each request sent by the WPWebDriver module:

                                                                                                                                                            +
                                                                                                                                                            actor: AcceptanceTester
                                                                                                                                                            +modules:
                                                                                                                                                            +    enabled:
                                                                                                                                                            +        - WPDb
                                                                                                                                                            +        - WPBrowser
                                                                                                                                                            +        - \Helper\Acceptance
                                                                                                                                                            +    config:
                                                                                                                                                            +        WPDb:
                                                                                                                                                            +            dsn: 'mysql:host=localhost;dbname=tests'
                                                                                                                                                            +            user: 'root'
                                                                                                                                                            +            password: 'root'
                                                                                                                                                            +            dump: 'tests/_data/dump.sql'
                                                                                                                                                            +            populate: true
                                                                                                                                                            +            cleanup: true
                                                                                                                                                            +            waitlock: 10
                                                                                                                                                            +            url: 'http://wp.test'
                                                                                                                                                            +            urlReplacement: true
                                                                                                                                                            +            tablePrefix: 'wp_'
                                                                                                                                                            +        WPBrowser:
                                                                                                                                                            +            url: 'http://wp.test'
                                                                                                                                                            +            adminUsername: 'admin'
                                                                                                                                                            +            adminPassword: 'admin'
                                                                                                                                                            +            adminPath: '/wp-admin'
                                                                                                                                                            +            headers:
                                                                                                                                                            +                X_WPBROWSER_REQUEST: 1
                                                                                                                                                            +                X_TEST_REQUEST: 1
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The two headers are sent on each HTTP request type, not just on GET type requests.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Using a different database to handle test requests

                                                                                                                                                            +

                                                                                                                                                            Now that each request made by the WPWebDriver module contains those two headers, it's time for WordPress to check those and change the database to use accordingly.

                                                                                                                                                            +

                                                                                                                                                            The database to use is set by the DB_NAME constant that is, in turn, set in the wp-config.php file.
                                                                                                                                                            +Different setups could involve more complex configurations for the wp-config.php file but, for the sake of simplicity, I assume the default WordPress wp-config.php file structure.
                                                                                                                                                            +In the example below, the default database name is wordpress, while the name of the test database is tests.

                                                                                                                                                            +
                                                                                                                                                            - define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            ++ if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {
                                                                                                                                                            ++     define( 'DB_NAME', 'tests' );
                                                                                                                                                            ++ } else {
                                                                                                                                                            ++     define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            ++ }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The diff shows the replacement done in the WordPress installation wp-config.php file.

                                                                                                                                                            +

                                                                                                                                                            For copy-and-paste pleasure, replace the line starting with:

                                                                                                                                                            +
                                                                                                                                                            define( 'DB_NAME', 'default_db_name' );
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            With this snippet:

                                                                                                                                                            +
                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {
                                                                                                                                                            +      define( 'DB_NAME', 'test_db_name' );
                                                                                                                                                            +} else {
                                                                                                                                                            +      define( 'DB_NAME', 'default_db_name' );
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Where default_db_name is the name of the database your test WordPress installation normally uses.

                                                                                                                                                            +

                                                                                                                                                            Happy, and safer, testing.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/tutorials/images/local-flywheel-adminer.png b/v3/tutorials/images/local-flywheel-adminer.png new file mode 100644 index 000000000..1fe9c4b4f Binary files /dev/null and b/v3/tutorials/images/local-flywheel-adminer.png differ diff --git a/v3/tutorials/images/local-flywheel-codecept-version.png b/v3/tutorials/images/local-flywheel-codecept-version.png new file mode 100644 index 000000000..e64d3e568 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-codecept-version.png differ diff --git a/v3/tutorials/images/local-flywheel-composer-init.png b/v3/tutorials/images/local-flywheel-composer-init.png new file mode 100644 index 000000000..0e78b8370 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-composer-init.png differ diff --git a/v3/tutorials/images/local-flywheel-create-database.png b/v3/tutorials/images/local-flywheel-create-database.png new file mode 100644 index 000000000..294662bd7 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-create-database.png differ diff --git a/v3/tutorials/images/local-flywheel-db-export.png b/v3/tutorials/images/local-flywheel-db-export.png new file mode 100644 index 000000000..451bebd8d Binary files /dev/null and b/v3/tutorials/images/local-flywheel-db-export.png differ diff --git a/v3/tutorials/images/local-flywheel-db-import.png b/v3/tutorials/images/local-flywheel-db-import.png new file mode 100644 index 000000000..2f6255db3 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-db-import.png differ diff --git a/v3/tutorials/images/local-flywheel-mac-db-creds.png b/v3/tutorials/images/local-flywheel-mac-db-creds.png new file mode 100644 index 000000000..a70952bfb Binary files /dev/null and b/v3/tutorials/images/local-flywheel-mac-db-creds.png differ diff --git a/v3/tutorials/images/local-flywheel-mac-wpbrowser-init-1.png b/v3/tutorials/images/local-flywheel-mac-wpbrowser-init-1.png new file mode 100644 index 000000000..9cad5f58b Binary files /dev/null and b/v3/tutorials/images/local-flywheel-mac-wpbrowser-init-1.png differ diff --git a/v3/tutorials/images/local-flywheel-mac-wpbrowser-init-2.png b/v3/tutorials/images/local-flywheel-mac-wpbrowser-init-2.png new file mode 100644 index 000000000..a5266c418 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-mac-wpbrowser-init-2.png differ diff --git a/v3/tutorials/images/local-flywheel-sites-path.png b/v3/tutorials/images/local-flywheel-sites-path.png new file mode 100644 index 000000000..ffbad733b Binary files /dev/null and b/v3/tutorials/images/local-flywheel-sites-path.png differ diff --git a/v3/tutorials/images/local-flywheel-win-db-creds.png b/v3/tutorials/images/local-flywheel-win-db-creds.png new file mode 100644 index 000000000..3af8637f0 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-win-db-creds.png differ diff --git a/v3/tutorials/images/local-flywheel-win-wpbrowser-init-1.png b/v3/tutorials/images/local-flywheel-win-wpbrowser-init-1.png new file mode 100644 index 000000000..34b219621 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-win-wpbrowser-init-1.png differ diff --git a/v3/tutorials/images/local-flywheel-win-wpbrowser-init-2.png b/v3/tutorials/images/local-flywheel-win-wpbrowser-init-2.png new file mode 100644 index 000000000..b97785f36 Binary files /dev/null and b/v3/tutorials/images/local-flywheel-win-wpbrowser-init-2.png differ diff --git a/v3/tutorials/images/local-lite-mac-db-creds.png b/v3/tutorials/images/local-lite-mac-db-creds.png new file mode 100644 index 000000000..3119940ad Binary files /dev/null and b/v3/tutorials/images/local-lite-mac-db-creds.png differ diff --git a/v3/tutorials/images/local-my-plugin-shows.png b/v3/tutorials/images/local-my-plugin-shows.png new file mode 100644 index 000000000..fd3f72741 Binary files /dev/null and b/v3/tutorials/images/local-my-plugin-shows.png differ diff --git a/v3/tutorials/images/mac-codecept-version.png b/v3/tutorials/images/mac-codecept-version.png new file mode 100644 index 000000000..51cc2e099 Binary files /dev/null and b/v3/tutorials/images/mac-codecept-version.png differ diff --git a/v3/tutorials/images/mac-composer-init.png b/v3/tutorials/images/mac-composer-init.png new file mode 100644 index 000000000..f77117f86 Binary files /dev/null and b/v3/tutorials/images/mac-composer-init.png differ diff --git a/v3/tutorials/images/mamp-create-db.png b/v3/tutorials/images/mamp-create-db.png new file mode 100644 index 000000000..1f18693cd Binary files /dev/null and b/v3/tutorials/images/mamp-create-db.png differ diff --git a/v3/tutorials/images/mamp-db-export.png b/v3/tutorials/images/mamp-db-export.png new file mode 100644 index 000000000..57c1ebdc8 Binary files /dev/null and b/v3/tutorials/images/mamp-db-export.png differ diff --git a/v3/tutorials/images/mamp-db-import.png b/v3/tutorials/images/mamp-db-import.png new file mode 100644 index 000000000..bcf2df2a5 Binary files /dev/null and b/v3/tutorials/images/mamp-db-import.png differ diff --git a/v3/tutorials/images/mamp-mac-dirs.png b/v3/tutorials/images/mamp-mac-dirs.png new file mode 100644 index 000000000..cede1dccb Binary files /dev/null and b/v3/tutorials/images/mamp-mac-dirs.png differ diff --git a/v3/tutorials/images/mamp-mac-ports.png b/v3/tutorials/images/mamp-mac-ports.png new file mode 100644 index 000000000..486768b7d Binary files /dev/null and b/v3/tutorials/images/mamp-mac-ports.png differ diff --git a/v3/tutorials/images/mamp-my-plugin-shows.png b/v3/tutorials/images/mamp-my-plugin-shows.png new file mode 100644 index 000000000..8f9133fb0 Binary files /dev/null and b/v3/tutorials/images/mamp-my-plugin-shows.png differ diff --git a/v3/tutorials/images/mamp-wp-installation-1.png b/v3/tutorials/images/mamp-wp-installation-1.png new file mode 100644 index 000000000..ce5543a9a Binary files /dev/null and b/v3/tutorials/images/mamp-wp-installation-1.png differ diff --git a/v3/tutorials/images/mamp-wpbrowser-init-1.png b/v3/tutorials/images/mamp-wpbrowser-init-1.png new file mode 100644 index 000000000..7598ffb37 Binary files /dev/null and b/v3/tutorials/images/mamp-wpbrowser-init-1.png differ diff --git a/v3/tutorials/images/mamp-wpbrowser-init-2.png b/v3/tutorials/images/mamp-wpbrowser-init-2.png new file mode 100644 index 000000000..b886d043f Binary files /dev/null and b/v3/tutorials/images/mamp-wpbrowser-init-2.png differ diff --git a/v3/tutorials/images/vvv-codecept-version.png b/v3/tutorials/images/vvv-codecept-version.png new file mode 100644 index 000000000..40dde49a0 Binary files /dev/null and b/v3/tutorials/images/vvv-codecept-version.png differ diff --git a/v3/tutorials/images/vvv-my-plugin-composer-init.png b/v3/tutorials/images/vvv-my-plugin-composer-init.png new file mode 100644 index 000000000..ba4991489 Binary files /dev/null and b/v3/tutorials/images/vvv-my-plugin-composer-init.png differ diff --git a/v3/tutorials/images/vvv-my-plugin-shows.png b/v3/tutorials/images/vvv-my-plugin-shows.png new file mode 100644 index 000000000..feb2bee49 Binary files /dev/null and b/v3/tutorials/images/vvv-my-plugin-shows.png differ diff --git a/v3/tutorials/images/vvv-ssh.png b/v3/tutorials/images/vvv-ssh.png new file mode 100644 index 000000000..4d8ae948d Binary files /dev/null and b/v3/tutorials/images/vvv-ssh.png differ diff --git a/v3/tutorials/images/vvv-up.png b/v3/tutorials/images/vvv-up.png new file mode 100644 index 000000000..25f513b55 Binary files /dev/null and b/v3/tutorials/images/vvv-up.png differ diff --git a/v3/tutorials/images/vvv-wp-browser-init-1.png b/v3/tutorials/images/vvv-wp-browser-init-1.png new file mode 100644 index 000000000..c4bbf5490 Binary files /dev/null and b/v3/tutorials/images/vvv-wp-browser-init-1.png differ diff --git a/v3/tutorials/images/vvv-wp-browser-init-2.png b/v3/tutorials/images/vvv-wp-browser-init-2.png new file mode 100644 index 000000000..e9a08fe68 Binary files /dev/null and b/v3/tutorials/images/vvv-wp-browser-init-2.png differ diff --git a/v3/tutorials/images/vvv-wp-db-backup.png b/v3/tutorials/images/vvv-wp-db-backup.png new file mode 100644 index 000000000..1d77634ba Binary files /dev/null and b/v3/tutorials/images/vvv-wp-db-backup.png differ diff --git a/v3/tutorials/images/wamp-codecept-version.png b/v3/tutorials/images/wamp-codecept-version.png new file mode 100644 index 000000000..758724c22 Binary files /dev/null and b/v3/tutorials/images/wamp-codecept-version.png differ diff --git a/v3/tutorials/images/wamp-composer-init.png b/v3/tutorials/images/wamp-composer-init.png new file mode 100644 index 000000000..fbfb7ac04 Binary files /dev/null and b/v3/tutorials/images/wamp-composer-init.png differ diff --git a/v3/tutorials/images/wamp-create-db.png b/v3/tutorials/images/wamp-create-db.png new file mode 100644 index 000000000..b657d8075 Binary files /dev/null and b/v3/tutorials/images/wamp-create-db.png differ diff --git a/v3/tutorials/images/wamp-db-export.png b/v3/tutorials/images/wamp-db-export.png new file mode 100644 index 000000000..61dd287cd Binary files /dev/null and b/v3/tutorials/images/wamp-db-export.png differ diff --git a/v3/tutorials/images/wamp-db-import.png b/v3/tutorials/images/wamp-db-import.png new file mode 100644 index 000000000..4ec724a35 Binary files /dev/null and b/v3/tutorials/images/wamp-db-import.png differ diff --git a/v3/tutorials/images/wamp-my-plugin-shows.png b/v3/tutorials/images/wamp-my-plugin-shows.png new file mode 100644 index 000000000..bd032656b Binary files /dev/null and b/v3/tutorials/images/wamp-my-plugin-shows.png differ diff --git a/v3/tutorials/images/wamp-virtualhost-creation-1.png b/v3/tutorials/images/wamp-virtualhost-creation-1.png new file mode 100644 index 000000000..44d0a7df3 Binary files /dev/null and b/v3/tutorials/images/wamp-virtualhost-creation-1.png differ diff --git a/v3/tutorials/images/wamp-virtualhost-creation-2.png b/v3/tutorials/images/wamp-virtualhost-creation-2.png new file mode 100644 index 000000000..64fddda4d Binary files /dev/null and b/v3/tutorials/images/wamp-virtualhost-creation-2.png differ diff --git a/v3/tutorials/images/wamp-wp-installation-1.png b/v3/tutorials/images/wamp-wp-installation-1.png new file mode 100644 index 000000000..ad206a953 Binary files /dev/null and b/v3/tutorials/images/wamp-wp-installation-1.png differ diff --git a/v3/tutorials/images/wamp-wpbrowser-init-1.png b/v3/tutorials/images/wamp-wpbrowser-init-1.png new file mode 100644 index 000000000..fbad77c2e Binary files /dev/null and b/v3/tutorials/images/wamp-wpbrowser-init-1.png differ diff --git a/v3/tutorials/images/wamp-wpbrowser-init-2.png b/v3/tutorials/images/wamp-wpbrowser-init-2.png new file mode 100644 index 000000000..867e228c5 Binary files /dev/null and b/v3/tutorials/images/wamp-wpbrowser-init-2.png differ diff --git a/v3/tutorials/images/wp-installation-2.png b/v3/tutorials/images/wp-installation-2.png new file mode 100644 index 000000000..736e8c3e4 Binary files /dev/null and b/v3/tutorials/images/wp-installation-2.png differ diff --git a/v3/tutorials/local-flywheel-setup/index.html b/v3/tutorials/local-flywheel-setup/index.html new file mode 100644 index 000000000..a758e1592 --- /dev/null +++ b/v3/tutorials/local-flywheel-setup/index.html @@ -0,0 +1,3448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Setting up wp-browser on Local by Flywheel to test a plugin - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Setting up wp-browser on Local by Flywheel to test a plugin

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser with Local by Flywheel to test a plugin

                                                                                                                                                            +

                                                                                                                                                            Note: the original version of this guide used, on Mac, the version of Local by Flywheel based on VirtualBox and Docker containers. That version has been replaced by a new one that will not use any virtualization layer. The UI is almost the same but, for back-compatibility purposes, I've not removed the references to the previous version; I have, instead, pointed out where the set up values and procedures might differ due to the changes.

                                                                                                                                                            +

                                                                                                                                                            Requirements

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A Mac or Windows machine
                                                                                                                                                            • +
                                                                                                                                                            • A working installation of Local By Flywheel.
                                                                                                                                                            • +
                                                                                                                                                            • You should be able to create sites and visit them from your browser without issues.
                                                                                                                                                            • +
                                                                                                                                                            • Composer installed and working on your terminal PATH, you should be able to run composer --version at the terminal and see the version correctly.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Install Local by Flywheel

                                                                                                                                                            +

                                                                                                                                                            This walk-through starts after Local by Flywheel has been installed and is correctly running on your machine; you can download Local from the site and follow the installation instructions.

                                                                                                                                                            +

                                                                                                                                                            In the context of this guide I'm assuming the sites directory is ~/Local Sites, the default "Sites Path" in Local preferences.

                                                                                                                                                            +

                                                                                                                                                            If your document root lies elsewhere, replace the ~/Local Sites path with the actual directory in each command.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Creating the databases and installing WordPress

                                                                                                                                                            +

                                                                                                                                                            Using Local UI create a new site:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • The site name is myplugin.
                                                                                                                                                            • +
                                                                                                                                                            • The site administrator user name is admin.
                                                                                                                                                            • +
                                                                                                                                                            • The site administrator password is password.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Once Local provisioned and installed the new site, open the "Database" administration tab and, depending on your OS, start a database administration UI or website. +In the image below I'm using Adminer:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Create a database called tests:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Make sure you can visit the WordPress installation at http://myplugin.local and that you can correctly access the administration area at http://myplugin.local/wp-admin.

                                                                                                                                                            +

                                                                                                                                                            Scaffolding the project folder

                                                                                                                                                            +

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            +

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins.
                                                                                                                                                            +Create the main plugin file in the WordPress installation plugins directory, in the ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin/my-plugin.php file:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +/**
                                                                                                                                                            + * Plugin Name: My plugin
                                                                                                                                                            + */ 
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the WordPress installation at http://myplugin.local/wp-admin/plugins.php.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Installing wp-browser

                                                                                                                                                            +

                                                                                                                                                            Open a terminal window and navigate to the plugin directory and initialize the Composer project:

                                                                                                                                                            +
                                                                                                                                                            cd ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin
                                                                                                                                                            +composer init
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. +Here is the composer.json file generated by the above answers:

                                                                                                                                                            +
                                                                                                                                                            {
                                                                                                                                                            +    "name": "local/my-plugin",
                                                                                                                                                            +    "type": "wordpress-plugin",
                                                                                                                                                            +    "require": {}
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev lucatume/wp-browser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder.
                                                                                                                                                            +To check Codeception is correctly installed run this command:

                                                                                                                                                            +
                                                                                                                                                            vendor/bin/codecept --version
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser

                                                                                                                                                            +

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            +

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the WordPress site "normal" database: this is the database that stores the data of the site I would see when visiting the local installation URL at http://myplugin.local.
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the database dedicated to the integration and "WordPress unit" tests: this database will be used to install WordPress during integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that your first step should be to backup the site database.

                                                                                                                                                            +

                                                                                                                                                            You can create a backup of the current site database contents using whatever tool the version of Local you're using provides.
                                                                                                                                                            +In this example I'm using Adminer:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            At any moment you can re-import the site database dump using, again, phpMyAdmin, under the "Import" tab:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Bootstrapping and configuring wp-browser

                                                                                                                                                            +

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            +
                                                                                                                                                            cd ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin
                                                                                                                                                            +vendor/bin/codecept init wpbrowser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The initialization guide will ask a number of questions.

                                                                                                                                                            +

                                                                                                                                                            Windows configuration

                                                                                                                                                            +

                                                                                                                                                            In the screenshots below are the answers I used to configure wp-browser on Windows.

                                                                                                                                                            +

                                                                                                                                                            Note that I've set up the database host using the values provided by Local UI, yours might differ depending on the version of Local you're using:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • +
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • +
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • +
                                                                                                                                                            • What is the path of the WordPress root directory? ~/Local Sites/myplugin/app/public
                                                                                                                                                            • +
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database used by the test site? localhost:10003
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost:10003
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the URL the test site? http://myplugin.local
                                                                                                                                                            • +
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@myplugin.local
                                                                                                                                                            • +
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • +
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • +
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • +
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • +
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            +

                                                                                                                                                            Mac configuration

                                                                                                                                                            +

                                                                                                                                                            In the screenshots below are the answers I used to configure wp-browser on Mac.

                                                                                                                                                            +

                                                                                                                                                            Note that I've set up the database host using the values provided by Local UI, yours might differ.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            This screenshot is from the previous version of Local, the one based on VirtualBox and Docker:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • +
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • +
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • +
                                                                                                                                                            • What is the path of the WordPress root directory? ~/Local Sites/myplugin/app/public
                                                                                                                                                            • +
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database used by the test site? /Users/lucatume/Library/Application Support/Local/run/FjKWfVMGd/mysql/mysqld.sock ( or 192.168.95.100:4055 on an older version of Local)
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database WPLoader should use? /Users/lucatume/Library/Application Support/Local/run/FjKWfVMGd/mysql/mysqld.sock (or 192.168.95.100:4055 on an older version of Local)
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the URL the test site? http://myplugin.local
                                                                                                                                                            • +
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@myplugin.local
                                                                                                                                                            • +
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • +
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • +
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • +
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • +
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            +

                                                                                                                                                            Setting up the starting database fixture

                                                                                                                                                            +

                                                                                                                                                            A "fixture", in testing terms, is a minimal, starting environment shared by all tests.
                                                                                                                                                            +In BDD it's the Background any scenario will share. +In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • +
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • +
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            You should set up this fixture "manually", using the site administration UI at http://myplugin.local/wp-admin.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            When you're done setting up the initial database fixture, export it using the "Export" tab of your database tool of choice, and move the file to the ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin/tests/_data/dump.sql directory.

                                                                                                                                                            +

                                                                                                                                                            There is one last step left to complete the setup.

                                                                                                                                                            +

                                                                                                                                                            Using the tests database in acceptance and functional tests

                                                                                                                                                            +

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            +

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            +

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the ~/Local Sites/myplugin/app/public/wp-config.php file, the DB_NAME constant is set to local.

                                                                                                                                                            +

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • If the request is a normal one, use the local database.
                                                                                                                                                            • +
                                                                                                                                                            • If the request comes from a test, use the tests database.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            In your IDE/text-editor of choice edit the ~/Local Sites/myplugin/app/public/wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            +
                                                                                                                                                            - define( 'DB_NAME', 'local' );
                                                                                                                                                            ++ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { 
                                                                                                                                                            ++    define( 'DB_NAME', 'tests' );
                                                                                                                                                            ++ } else {
                                                                                                                                                            ++    define( 'DB_NAME', 'local' );
                                                                                                                                                            ++ }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            +
                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {
                                                                                                                                                            +        define( 'DB_NAME', 'tests' );
                                                                                                                                                            +} else {
                                                                                                                                                            +        define( 'DB_NAME', 'local' );
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            +
                                                                                                                                                            headers:
                                                                                                                                                            +    X_TEST_REQUEST: 1
                                                                                                                                                            +    X_WPBROWSER_REQUEST: 1
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers.
                                                                                                                                                            +Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            +

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            +

                                                                                                                                                            Sanity check

                                                                                                                                                            +

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            +

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            +

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works.
                                                                                                                                                            +Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            +
                                                                                                                                                            cd ~/Local Sites/myplugin/app/public/wp-content/plugins/my-plugin 
                                                                                                                                                            +vendor/bin/codecept run acceptance
                                                                                                                                                            +vendor/bin/codecept run functional
                                                                                                                                                            +vendor/bin/codecept run wpunit
                                                                                                                                                            +vendor/bin/codecept run unit
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept to see a list of the available commands.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/tutorials/mamp-mac-setup/index.html b/v3/tutorials/mamp-mac-setup/index.html new file mode 100644 index 000000000..22dcd2f7d --- /dev/null +++ b/v3/tutorials/mamp-mac-setup/index.html @@ -0,0 +1,3358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Setting up wp-browser on MAMP for Mac to test a plugin - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Setting up wp-browser on MAMP for Mac to test a plugin

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser with MAMP on Mac to test a plugin

                                                                                                                                                            +

                                                                                                                                                            Requirements

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A Mac machine
                                                                                                                                                            • +
                                                                                                                                                            • A working installation of MAMP.
                                                                                                                                                            • +
                                                                                                                                                            • You should be able to create sites and visit them from your browser without issues.
                                                                                                                                                            • +
                                                                                                                                                            • Composer installed and working on your terminal PATH, you should be able to run composer --version at the terminal and see the version correctly.
                                                                                                                                                            • +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The version of MAMP used in this tutorial is the free, non PRO, one. MAMP PRO provides more features, but the setup instructions should remain valid.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Install and configure MAMP

                                                                                                                                                            +

                                                                                                                                                            This walk-through starts after MAMP has been installed and is correctly running on the host machine; you can download MAMP from the site and follow the installation instructions.
                                                                                                                                                            +In the context of this guide I'm assuming the "Document Root" directory is the default one, in the /Applications/MAMP/htdocs directory.
                                                                                                                                                            +If your document root lies elsewhere, replace the /Applications/MAMP/htdocs path with the actual directory in each command.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Creating the databases and installing WordPress

                                                                                                                                                            +

                                                                                                                                                            Go to the http://localhost/phpMyAdmin/ page and create two new databases:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • wordpress is the database you will use for WordPress
                                                                                                                                                            • +
                                                                                                                                                            • tests is the database you will use for the tests
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Unzip the the WordPress files into the /Applications/MAMP/htdocs and head over to http://localhost to install WordPress.

                                                                                                                                                            +

                                                                                                                                                            The database credentials for the installation are:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Database name: wordpress
                                                                                                                                                            • +
                                                                                                                                                            • Database user: root
                                                                                                                                                            • +
                                                                                                                                                            • Database password: root
                                                                                                                                                            • +
                                                                                                                                                            • Database host: localhost
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Use admin as administrator user name and password as password for the administrator user.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Make sure you can visit the WordPress installation at http://localhost and that you can correctly access the administration area at http://localhost/wp-admin.

                                                                                                                                                            +

                                                                                                                                                            Scaffolding the project folder

                                                                                                                                                            +

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            +

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins.
                                                                                                                                                            +Create the main plugin file in the WordPress installation plugins directory, in the /Applications/MAMP/htdocs/wp-content/plugins/my-plugin/my-plugin.php file:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +/**
                                                                                                                                                            + * Plugin Name: My plugin
                                                                                                                                                            + */ 
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the WordPress installation at http://localhost/wp-admin/plugins.php.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Installing wp-browser

                                                                                                                                                            +

                                                                                                                                                            Open a terminal window and navigate to the plugin directory and initialize the Composer project:

                                                                                                                                                            +
                                                                                                                                                            cd /Applications/MAMP/htdocs/wp-content/plugins/my-plugin
                                                                                                                                                            +composer init
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. +Here is the composer.json file generated by the above answers:

                                                                                                                                                            +
                                                                                                                                                            {
                                                                                                                                                            +    "name": "mamp/my-plugin",
                                                                                                                                                            +    "type": "wordpress-plugin",
                                                                                                                                                            +    "require": {}
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev lucatume/wp-browser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder.
                                                                                                                                                            +To check Codeception is correctly installed run this command:

                                                                                                                                                            +
                                                                                                                                                            vendor/bin/codecept --version
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser

                                                                                                                                                            +

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            +

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the WordPress site "normal" database: this is the database that stores the data of the site I would see when visiting the local installation URL at http://localhost.
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the database dedicated to the integration and "WordPress unit" tests: this database will be used to install WordPress during integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that your first step should be to backup the site database.

                                                                                                                                                            +

                                                                                                                                                            You can create a backup of the current site database contents using phpMyAdmin, at http://localhost/phpMyAdmin/, under the "Export" tab:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            At any moment you can re-import the site database dump using, again, phpMyAdmin, under the "Import" tab:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Bootstrapping and configuring wp-browser

                                                                                                                                                            +

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            +
                                                                                                                                                            cd /Applications/MAMP/htdocs/wp-content/plugins/my-plugin
                                                                                                                                                            +vendor/bin/codecept init wpbrowser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The initialization guide will ask a number of questions.
                                                                                                                                                            +In the screenshots below are the answers I used to configure wp-browser.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • +
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • +
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • +
                                                                                                                                                            • What is the path of the WordPress root directory? /Applications/MAMP/htdocs
                                                                                                                                                            • +
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database used by the test site? localhost
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the URL the test site? http://localhost
                                                                                                                                                            • +
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@wp.test
                                                                                                                                                            • +
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • +
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • +
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • +
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • +
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            +

                                                                                                                                                            Setting up the starting database fixture

                                                                                                                                                            +

                                                                                                                                                            A "fixture", in testing terms, is a minimal, starting environment shared by all tests.
                                                                                                                                                            +In BDD it's the Background any scenario will share. +In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • +
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • +
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            You should set up this fixture "manually", using the site administration UI at http://localhost/wp-admin.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            When you're done setting up the initial database fixture, export it using the "Export" tab of phpMyAdmin, at http://localhost/phpMyAdmin/ and move the file to the /Applications/MAMP/htdocs/wp-content/plugins/my-plugin/tests/_data/dump.sql directory.

                                                                                                                                                            +

                                                                                                                                                            There is one last step left to complete the setup.

                                                                                                                                                            +

                                                                                                                                                            Using the tests database in acceptance and functional tests

                                                                                                                                                            +

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            +

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            +

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the /Applications/MAMP/htdocs/wp-config.php file, the DB_NAME constant is set to wordpress.

                                                                                                                                                            +

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • If the request is a normal one, use the wordpress database.
                                                                                                                                                            • +
                                                                                                                                                            • If the request comes from a test, use the tests database.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            In your IDE/text-editor of choice edit the /Applications/MAMP/htdocs/wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            +
                                                                                                                                                            - define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            ++ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { 
                                                                                                                                                            ++    define( 'DB_NAME', 'tests' );
                                                                                                                                                            ++ } else {
                                                                                                                                                            ++    define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            ++ }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            +
                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {
                                                                                                                                                            +        define( 'DB_NAME', 'tests' );
                                                                                                                                                            +} else {
                                                                                                                                                            +        define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            +
                                                                                                                                                            headers:
                                                                                                                                                            +    X_TEST_REQUEST: 1
                                                                                                                                                            +    X_WPBROWSER_REQUEST: 1
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers.
                                                                                                                                                            +Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            +

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            +

                                                                                                                                                            Sanity check

                                                                                                                                                            +

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            +

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            +

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works.
                                                                                                                                                            +Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            +
                                                                                                                                                            cd /Applications/MAMP/htdocs/wp-content/plugins/my-plugin 
                                                                                                                                                            +vendor/bin/codecept run acceptance
                                                                                                                                                            +vendor/bin/codecept run functional
                                                                                                                                                            +vendor/bin/codecept run wpunit
                                                                                                                                                            +vendor/bin/codecept run unit
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept to see a list of the available commands.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/tutorials/vvv-setup/index.html b/v3/tutorials/vvv-setup/index.html new file mode 100644 index 000000000..c89777017 --- /dev/null +++ b/v3/tutorials/vvv-setup/index.html @@ -0,0 +1,3446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Setting up wp-browser on VVV to test a plugin - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Setting up wp-browser on VVV to test a plugin

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser on VVV to test a plugin

                                                                                                                                                            +

                                                                                                                                                            Requirements

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A Windows, Linux or Mac machine (I'll call this the "host machine" or just "host").
                                                                                                                                                            • +
                                                                                                                                                            • A working installation of VVV; you should be able to navigate to VVV root directory, run the vagrant up command, and have VVV up and running.
                                                                                                                                                            • +
                                                                                                                                                            • On the VVV installation you should be able to visit the two default sites URLs without issues; the two default sites addresses are:
                                                                                                                                                                +
                                                                                                                                                              • http://one.wordpress.test
                                                                                                                                                              • +
                                                                                                                                                              • http://two.wordpress.test
                                                                                                                                                              • +
                                                                                                                                                              +
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Why VVV?

                                                                                                                                                            +

                                                                                                                                                            The VVV project provides a "a Vagrant configuration for developing with WordPress" and is an excellent, no-frills, starting point to develop WordPress projects (themes, plugins and whole sites.
                                                                                                                                                            +Based on Vagrant and Virtual Box, VVV removes the differences between systems by providing a uniform, Ubuntu Linux based, virtual machine that will bahave the same on Windows, Linux and Mac. +Configuring it to run WordPress tests is easy: let's get started.

                                                                                                                                                            +

                                                                                                                                                            Check VVV works correctly

                                                                                                                                                            +

                                                                                                                                                            This walk-through starts after VVV has been installed and is running on the host machine; the installation guide is clear and simple to follow and I'm not duplicating it here.
                                                                                                                                                            +In the context of this guide I'm assuming VVV lives in the ~/Repos/VVV directory, that we are working on the my-plugin project and that the plugin is being developed in the default (wordpress-one) WordPress installation provided by the box.
                                                                                                                                                            +If your VVV installation lies elsewhere, replace the ~/Repos/VVV with the actual directory in each command.

                                                                                                                                                            +

                                                                                                                                                            After completing the installation of VVV navigate to VVV root folder and run the vagrant up command:

                                                                                                                                                            +
                                                                                                                                                            cd ~/Repos/VVV
                                                                                                                                                            +vagrant up
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            vagrant up command result

                                                                                                                                                            +

                                                                                                                                                            After the automatic bootstrap and initialization process completed, VVV makes two WordPress sites available:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • http://one.wordpress.test/ is the first default site address.
                                                                                                                                                            • +
                                                                                                                                                            • http://two.wordpress.test/ is the second default site address.
                                                                                                                                                            • +
                                                                                                                                                            • http://vvv.test/ is VVV dashboard address.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            You should be able to reach each one of the URLs above without issues, should this not be the case something during VVV setup did not go according to the plan and you should fix it before moving on.

                                                                                                                                                            +

                                                                                                                                                            If the sanity check above is complete it's time to move to the following part specific to Codeception and wp-browser setup.

                                                                                                                                                            +

                                                                                                                                                            In and out, host and guest

                                                                                                                                                            +

                                                                                                                                                            The Vagrant box provided by VVV goes beyond a simple MySQL, PHP and Ngnix server stack and provides a complete WordPress development environment; tools like Composer, [grunt-cli][4992-0003], and [wp-cli][4992-0006] are ready to use.

                                                                                                                                                            +

                                                                                                                                                            This allows the entire development, when it comes to the CLI tools, to happen in the virtual machine and not outside of it.

                                                                                                                                                            +

                                                                                                                                                            "Inside the virtual machine" means the first CLI instruction to run from the ~/Repos/VVV folder (assuming that is the folder where VVV was installed) is this:

                                                                                                                                                            +
                                                                                                                                                            cd ~/Repos/VVV
                                                                                                                                                            +vagrant ssh
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            vagrant ssh command result

                                                                                                                                                            +

                                                                                                                                                            This will connect, via SSH, to the virtual machine as the vagrant user.
                                                                                                                                                            +To exit from the SSH session inside the box, just type exit and return.

                                                                                                                                                            +

                                                                                                                                                            Note: any further instruction I'm showing here, beside the code editing that will happen in a dedicated PHP IDE like [PHPStorm][4992-0004] or [Sublime Text][4992-0005] on the host machine, will happen "inside the virtual machine".

                                                                                                                                                            +

                                                                                                                                                            When I say "host machine" I mean your laptop, desktop or whatever computer you're working on; when I say "guest machine" I mean VVV virtual machine; this is usually the case for any virtual-ish setup (Vagrant, Docker and the like).

                                                                                                                                                            +

                                                                                                                                                            Scaffolding the project folder

                                                                                                                                                            +

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            +

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins.
                                                                                                                                                            +Create the main plugin file in the http://one.wordpress.test installation plugins directory, in the ~/Repos/VVV/www/wordpress-one/public_html/wp-content/plugins/my-plugin/my-plugin.php file:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +/**
                                                                                                                                                            + * Plugin Name: My plugin
                                                                                                                                                            + */ 
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the VVV default WordPress installation at http://one.wordpress.test/wp-admin/plugins.php.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            By default, VVV administrator user name is admin and password is password.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Installing wp-browser

                                                                                                                                                            +

                                                                                                                                                            Since Composer is provided from VVV, installing wp-browser requires entering the virtual machine (if you did not already):

                                                                                                                                                            +
                                                                                                                                                            cd ~/Repos/VVV
                                                                                                                                                            +vagrant ssh
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Once inside navigate to the plugins folder.
                                                                                                                                                            +The path is now relative to VVV filesystem structure so it won't be the same as the one used above that was, instead, in the context of the "host machine":

                                                                                                                                                            +
                                                                                                                                                            cd /srv/www/wordpress-one/public_html/wp-content/plugins/my-plugin 
                                                                                                                                                            +composer init
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. +Here is the composer.json file generated by the above answers:

                                                                                                                                                            +
                                                                                                                                                            {
                                                                                                                                                            +    "name": "vagrant/my-plugin",
                                                                                                                                                            +    "type": "wordpress-plugin",
                                                                                                                                                            +    "require": {}
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev lucatume/wp-browser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder.
                                                                                                                                                            +To check Codeception is correctly installed run this command:

                                                                                                                                                            +
                                                                                                                                                            vendor/bin/codecept --version
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser

                                                                                                                                                            +

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            +

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the WordPress site "normal" database: this is the database that stores the data of the site I would see when visiting the local installation URL (http://one.wordpress.test in the case of the VVV default installation).
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the database dedicated to the integration and "WordPress unit" tests: this database will be used to install WordPress during integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that if I am using VVV for my day to day WordPress development my first step should be to backup the site database.

                                                                                                                                                            +

                                                                                                                                                            You can create a backup of the current site database contents using wp-cli from within the virtual machine:

                                                                                                                                                            +
                                                                                                                                                            cd /srv/www/wordpress-one/public_html
                                                                                                                                                            +wp db export wordpress-one-backup.sql
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            At any moment you can re-import the site database dump using this command, the site database will be reset to the state it was when you created the database dump:

                                                                                                                                                            +
                                                                                                                                                            cd /srv/www/wordpress-one/public_html
                                                                                                                                                            +wp db import wordpress-one-backup.sql
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Creating the database dedicated to the tests

                                                                                                                                                            +

                                                                                                                                                            wp-browser will use the databases it works on in a destructive way: between tests the data will be lost.

                                                                                                                                                            +

                                                                                                                                                            After the backup you should have done in the previous step, the next step is creating a database dedicated to the test.

                                                                                                                                                            +

                                                                                                                                                            At the VVV box command line run:

                                                                                                                                                            +
                                                                                                                                                            mysql -u root -p -e "CREATE DATABASE if not exists tests"
                                                                                                                                                            +mysql -u root -p -e "GRANT ALL PRIVILEGES ON tests.* TO 'wp'@'localhost';"
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            When prompted for the password enter root. +The first command creates the tests database, if it does not exist; the second command grants the wp user all privileges on it.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            In VVV the root database user name is root and the password is root.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Check the database was correctly created running this command:

                                                                                                                                                            +
                                                                                                                                                            mysql -u root -p -e "SHOW DATABASES"
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The tests database should be present in the list.

                                                                                                                                                            +

                                                                                                                                                            Bootstrapping and configuring wp-browser

                                                                                                                                                            +

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            +
                                                                                                                                                            cd /srv/www/wordpress-one/public_html/wp-content/plugins/my-plugin
                                                                                                                                                            +vendor/bin/codecept init wpbrowser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The initialization guide will ask a number of questions.
                                                                                                                                                            +In the screenshots below are the answers I used to configure wp-browser.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • +
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • +
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • +
                                                                                                                                                            • What is the path of the WordPress root directory? /srv/www/wordpress-one/public_html
                                                                                                                                                            • +
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database used by the test site? localhost
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the URL the test site? http://one.wordpress.test
                                                                                                                                                            • +
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@one.wordpress.test
                                                                                                                                                            • +
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • +
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • +
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • +
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • +
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            +

                                                                                                                                                            Setting up the starting database fixture

                                                                                                                                                            +

                                                                                                                                                            A "fixture", in testing terms, is a minimal, starting environment shared by all tests.
                                                                                                                                                            +In BDD it's the Background any scenario will share. +In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • +
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • +
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            You can set up this fixture "manually", using the site administration UI at http://one.wordpress.test/wp-admin, or use wp-cli and save precious time.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            As it's been the case so far, I'm running the following command from within the VVV box (use vagrant ssh to log in):

                                                                                                                                                            +
                                                                                                                                                            cd /srv/www/wordpress-one/public_html
                                                                                                                                                            +wp site empty --yes --uploads
                                                                                                                                                            +wp plugin deactivate --all
                                                                                                                                                            +wp plugin activate my-plugin
                                                                                                                                                            +wp db export wp-content/plugins/my-plugin/tests/_data/dump.sql
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The initial database fixture has been created, now there's one last step to complete.

                                                                                                                                                            +

                                                                                                                                                            Using the tests database in acceptance and functional tests

                                                                                                                                                            +

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            +

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            +

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the /srv/www/wordpress-one/public_html/wp-config.php file, the DB_NAME constant is set to wordpress-one.

                                                                                                                                                            +

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • If the request is a normal one, use the wordpress-one database.
                                                                                                                                                            • +
                                                                                                                                                            • If the request comes from a test, use the tests database.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            In your IDE/text-editor of choice edit the ~/Repos/VVV/www/wordpress-one/public_html/wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            +
                                                                                                                                                            - define( 'DB_NAME', 'wordpress-one' );
                                                                                                                                                            ++ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { 
                                                                                                                                                            ++    define( 'DB_NAME', 'tests' );
                                                                                                                                                            ++ } else {
                                                                                                                                                            ++    define( 'DB_NAME', 'wordpress-one' );
                                                                                                                                                            ++ }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            +
                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {
                                                                                                                                                            +        define( 'DB_NAME', 'tests' );
                                                                                                                                                            +} else {
                                                                                                                                                            +        define( 'DB_NAME', 'wordpress-one' );
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            +
                                                                                                                                                            headers:
                                                                                                                                                            +    X_TEST_REQUEST: 1
                                                                                                                                                            +    X_WPBROWSER_REQUEST: 1
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers.
                                                                                                                                                            +Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            +

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            +

                                                                                                                                                            Sanity check

                                                                                                                                                            +

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            +

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            +

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works.
                                                                                                                                                            +Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            +
                                                                                                                                                            cd /srv/www/wordpress-one/public_html/wp-content/plugins/my-plugin 
                                                                                                                                                            +vendor/bin/codecept run acceptance
                                                                                                                                                            +vendor/bin/codecept run functional
                                                                                                                                                            +vendor/bin/codecept run wpunit
                                                                                                                                                            +vendor/bin/codecept run unit
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept to see a list of the available commands.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file diff --git a/v3/tutorials/wamp-setup/index.html b/v3/tutorials/wamp-setup/index.html new file mode 100644 index 000000000..2f3d79c25 --- /dev/null +++ b/v3/tutorials/wamp-setup/index.html @@ -0,0 +1,3360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Setting up wp-browser on WAMP for Windows to test a plugin - wp-browser docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +

                                                                                                                                                            Setting up wp-browser on WAMP for Windows to test a plugin

                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            This is the documentation for version 3 of the project. +The current version is version 4 and the documentation can be found here.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser with WAMP on Windows to test a plugin

                                                                                                                                                            +

                                                                                                                                                            Requirements

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A Windows machine
                                                                                                                                                            • +
                                                                                                                                                            • A working installation of WAMP.
                                                                                                                                                            • +
                                                                                                                                                            • You should be able to create sites and visit them from your browser without issues.
                                                                                                                                                            • +
                                                                                                                                                            • Composer installed and working on your terminal PATH, you should be able to run composer --version at the terminal and see the version correctly.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Install and configure WAMP

                                                                                                                                                            +

                                                                                                                                                            This walk-through starts after WAMP has been installed and is correctly running on the host machine; you can download WAMP from the site and follow the installation instructions.
                                                                                                                                                            +In the context of this guide I'm installing the test WordPress installation in the C:\wamp64\www\wp directory. +If your installation lies elsewhere, replace the C:\wamp64\www\wp path with the actual directory in each command.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Creating the databases and installing WordPress

                                                                                                                                                            +

                                                                                                                                                            Go to the http://localhost/phpmyadmin/index.php page and create two new databases:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • wordpress is the database you will use for WordPress
                                                                                                                                                            • +
                                                                                                                                                            • tests is the database you will use for the tests
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The default database user is root, the default password is empty.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Unzip the the WordPress files into the C:\wamp64\www\wp and head over to http://localhost/wp to install WordPress.
                                                                                                                                                            +The database credentials for the installation are:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Database name: wordpress
                                                                                                                                                            • +
                                                                                                                                                            • Database user: root
                                                                                                                                                            • +
                                                                                                                                                            • Database password is empty
                                                                                                                                                            • +
                                                                                                                                                            • Database host: localhost
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Use admin as administrator user name and password as password for the administrator user.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Make sure you can visit the WordPress installation at http://localhost/wp and that you can correctly access the administration area at http://localhost/wp/wp-admin.

                                                                                                                                                            +

                                                                                                                                                            Scaffolding the project folder

                                                                                                                                                            +

                                                                                                                                                            I'm assuming the scope of the development is to test the my-plugin plugin.

                                                                                                                                                            +

                                                                                                                                                            The first step is to create the bare minimum code required to make the plugin show up among the available WordPress plugins.
                                                                                                                                                            +Create the main plugin file in the WordPress installation plugins directory, in the C:\wamp64\www\wp\wp-content\plugins\my-plugin\my-plugin.php file:

                                                                                                                                                            +
                                                                                                                                                            <?php
                                                                                                                                                            +/**
                                                                                                                                                            + * Plugin Name: My plugin
                                                                                                                                                            + */ 
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The plugin should now show up, activate and deactivate correctly, among the plugins listed in the WordPress installation at http://localhost/wp/wp-admin/plugins.php.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Installing wp-browser

                                                                                                                                                            +

                                                                                                                                                            Open a terminal window and navigate to the plugin directory and initialize the Composer project.
                                                                                                                                                            +I'm using Cmder as terminal emulator on Windows, but you can use the default one.

                                                                                                                                                            +
                                                                                                                                                            cd C:\wamp64\www\wp\wp-content\plugins\my-plugin
                                                                                                                                                            +composer init
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Composer will ask some questions to initialize the project, for the sake of this small guide the answers are not relevant. +Here is the composer.json file generated by the above answers:

                                                                                                                                                            +
                                                                                                                                                            {
                                                                                                                                                            +    "name": "wamp/my-plugin",
                                                                                                                                                            +    "type": "wordpress-plugin",
                                                                                                                                                            +    "require": {}
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Next require lucatume/wp-browser as a development dependency:

                                                                                                                                                            +
                                                                                                                                                            composer require --dev lucatume/wp-browser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Composer installs any dependency binary file, an executable file, in the project vendor/bin folder.
                                                                                                                                                            +To check Codeception is correctly installed run this command:

                                                                                                                                                            +
                                                                                                                                                            vendor\bin\codecept.bat --version
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Since wp-browser requires Codeception, there is no need to require Codeception explicitly as a development dependency.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Setting up wp-browser

                                                                                                                                                            +

                                                                                                                                                            For those that might get lost while trying to set up wp-browser for the first time the VVV context provides an excellent base to understand the process.

                                                                                                                                                            +

                                                                                                                                                            wp-browser needs to know:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • Where the WordPress installation files are located: they will be loaded in integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the WordPress site "normal" database: this is the database that stores the data of the site I would see when visiting the local installation URL at http://localhost/wp.
                                                                                                                                                            • +
                                                                                                                                                            • How to connect to the database dedicated to the integration and "WordPress unit" tests: this database will be used to install WordPress during integration and "WordPress unit" tests.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Any test suite using a database should never run on a database containing data of any value; this means that your first step should be to backup the site database.

                                                                                                                                                            +

                                                                                                                                                            You can create a backup of the current site database contents using phpMyAdmin, at http://localhost/phpmyadmin/, under the "Export" tab:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            At any moment you can re-import the site database dump using, again, phpMyAdmin, under the "Import" tab:

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Bootstrapping and configuring wp-browser

                                                                                                                                                            +

                                                                                                                                                            After the backup is done it's time to bootstrap wp-browser using its interactive mode:

                                                                                                                                                            +
                                                                                                                                                            cd C:\wamp64\www\wp\wp-content\plugins\my-plugin
                                                                                                                                                            +vendor/bin/codecept.bat init wpbrowser
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The initialization guide will ask a number of questions.
                                                                                                                                                            +In the screenshots below are the answers I used to configure wp-browser.

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            +

                                                                                                                                                            Below a complete list of each answer:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • I acknowledge wp-browser should run on development servers... y
                                                                                                                                                            • +
                                                                                                                                                            • Would you like to set up the suites interactively now? y
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the acceptance suite to be called? acceptance
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the functional suite to be called? functional
                                                                                                                                                            • +
                                                                                                                                                            • How would you like the WordPress unit and integration suite to be called? wpunit
                                                                                                                                                            • +
                                                                                                                                                            • How would you like to call the env configuration file? .env.testing
                                                                                                                                                            • +
                                                                                                                                                            • What is the path of the WordPress root directory? C:/wamp64/www/wp
                                                                                                                                                            • +
                                                                                                                                                            • What is the path, relative to WordPress root URL, of the admin area of the test site? /wp-admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database used by the test site? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database used by the test site? localhost
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database used by the test site? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database used by the test site? ``
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database used by the test site? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the name of the test database WPLoader should use? tests
                                                                                                                                                            • +
                                                                                                                                                            • What is the host of the test database WPLoader should use? localhost
                                                                                                                                                            • +
                                                                                                                                                            • What is the user of the test database WPLoader should use? root
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the test database WPLoader should use? ``
                                                                                                                                                            • +
                                                                                                                                                            • What is the table prefix of the test database WPLoader should use? wp_
                                                                                                                                                            • +
                                                                                                                                                            • What is the URL the test site? http://localhost/wp
                                                                                                                                                            • +
                                                                                                                                                            • What is the email of the test site WordPress administrator? admin@wp.test
                                                                                                                                                            • +
                                                                                                                                                            • What is the title of the test site? My Plugin Test
                                                                                                                                                            • +
                                                                                                                                                            • What is the login of the administrator user of the test site? admin
                                                                                                                                                            • +
                                                                                                                                                            • What is the password of the administrator user of the test site? password
                                                                                                                                                            • +
                                                                                                                                                            • Are you testing a plugin, a theme or a combination of both (both)? plugin
                                                                                                                                                            • +
                                                                                                                                                            • What is the folder/plugin.php name of the plugin? my-plugin/my-plugin.php
                                                                                                                                                            • +
                                                                                                                                                            • Does your project needs additional plugins to be activated to work? no
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            Codeception will build the suites for the first time and should be ready to go.

                                                                                                                                                            +

                                                                                                                                                            Setting up the starting database fixture

                                                                                                                                                            +

                                                                                                                                                            A "fixture", in testing terms, is a minimal, starting environment shared by all tests.
                                                                                                                                                            +In BDD it's the Background any scenario will share. +In the case of a plugin the minimal, starting environment is the following:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • A fresh WordPress installation empty of any content.
                                                                                                                                                            • +
                                                                                                                                                            • WordPress using its default theme.
                                                                                                                                                            • +
                                                                                                                                                            • The only active plugin is the one you're testing, in this example: my-plugin.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            You should set up this fixture "manually", using the site administration UI at http://localhost/wp/wp-admin.

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            The following command will empty the site, backup any content you care about first!

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            When you're done setting up the initial database fixture, export it using the "Export" tab of phpMyAdmin, at http://localhost/phpmyadmin/ and move the file to the C:\wamp64\www\wp\wp-content\plugins\my-plugin\tests\_data\dump.sql directory.

                                                                                                                                                            +

                                                                                                                                                            There is one last step left to complete the setup.

                                                                                                                                                            +

                                                                                                                                                            Using the tests database in acceptance and functional tests

                                                                                                                                                            +

                                                                                                                                                            Acceptance and functional tests will act as users, navigating to the site pages and making requests as a user would.

                                                                                                                                                            +

                                                                                                                                                            This means that WordPress will load, and with it its wp-config.php file, to handle the requests made by the tests.

                                                                                                                                                            +

                                                                                                                                                            During the setup phase I've specified the database to be used for acceptance and functional tests as tests but, looking at the contents of the C:\wamp64\www\wp\wp-config.php file, the DB_NAME constant is set to wordpress.

                                                                                                                                                            +

                                                                                                                                                            What we'll do now means:

                                                                                                                                                            +
                                                                                                                                                              +
                                                                                                                                                            • If the request is a normal one, use the wordpress database.
                                                                                                                                                            • +
                                                                                                                                                            • If the request comes from a test, use the tests database.
                                                                                                                                                            • +
                                                                                                                                                            +

                                                                                                                                                            In your IDE/text-editor of choice edit the C:\wamp64\www\wp\wp-config.php and replace the line defining the DB_NAME constant like this:

                                                                                                                                                            +
                                                                                                                                                            - define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            ++ if( isset( $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) && $_SERVER['HTTP_X_WPBROWSER_REQUEST'] ) { 
                                                                                                                                                            ++    define( 'DB_NAME', 'tests' );
                                                                                                                                                            ++ } else {
                                                                                                                                                            ++    define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            ++ }
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Here's the copy-and-paste friendly version:

                                                                                                                                                            +
                                                                                                                                                            if( isset( $_SERVER['HTTP_X_TEST_REQUEST'] ) && $_SERVER['HTTP_X_TEST_REQUEST'] ) {
                                                                                                                                                            +        define( 'DB_NAME', 'tests' );
                                                                                                                                                            +} else {
                                                                                                                                                            +        define( 'DB_NAME', 'wordpress' );
                                                                                                                                                            +}
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            If you look at the tests/acceptance.suite.yml and tests/functional.suite.yml files, respectively the acceptance and functional suite configuration files, you will see these entries in the WPBrowser module configuration:

                                                                                                                                                            +
                                                                                                                                                            headers:
                                                                                                                                                            +    X_TEST_REQUEST: 1
                                                                                                                                                            +    X_WPBROWSER_REQUEST: 1
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            This means that, with each HTTP request done during tests, the module will send the two headers.
                                                                                                                                                            +Those headers are read, on the WordPress side, using the $_SERVER['HTTP_X_TEST_REQUEST'] and $_SERVER['X_WPBROWSER_REQUEST'] variables.

                                                                                                                                                            +

                                                                                                                                                            Codeception and wp-browser are ready to run and the test-drive development can start.

                                                                                                                                                            +

                                                                                                                                                            Sanity check

                                                                                                                                                            +

                                                                                                                                                            Before starting to write tests, take a moment to run each suite separately and make sure all is set up correctly.

                                                                                                                                                            +

                                                                                                                                                            If you run into issues, there's a chance you forgot something along the way, please take the time to read this tutorial a second time before opening an issue.

                                                                                                                                                            +

                                                                                                                                                            You have created 4 suites, each suite has at least one example test to make sure all works.
                                                                                                                                                            +Run each suite and make sure all tests succeed, from within the box run:

                                                                                                                                                            +
                                                                                                                                                            cd C:\wamp64\www\wp\wp-content\plugins\my-plugin 
                                                                                                                                                            +vendor/bin/codecept run acceptance
                                                                                                                                                            +vendor/bin/codecept run functional
                                                                                                                                                            +vendor/bin/codecept run wpunit
                                                                                                                                                            +vendor/bin/codecept run unit
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            You're now run to customize the suites to your liking or start writing tests, run vendor/bin/codecept.bat to see a list of the available commands.

                                                                                                                                                            + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            + + + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + + + \ No newline at end of file